From 253c7d3b9425681d61b781ecd388c9ec198c310b Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Fri, 31 Jul 2009 20:11:06 +0000 Subject: [PATCH] fixed properties git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@799736 13f79535-47bb-0310-9956-ffa450edef68 --- .../math/stat/clustering/Clusterable.java | 92 +- .../math/util/OpenIntToFieldHashMap.java | 1232 ++++++++--------- .../SingularValueDecompositionImplTest.java | 0 .../math/linear/SparseFieldVectorTest.java | 436 +++--- 4 files changed, 880 insertions(+), 880 deletions(-) mode change 100755 => 100644 src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java diff --git a/src/java/org/apache/commons/math/stat/clustering/Clusterable.java b/src/java/org/apache/commons/math/stat/clustering/Clusterable.java index 3a3310b5e..2be0367e2 100644 --- a/src/java/org/apache/commons/math/stat/clustering/Clusterable.java +++ b/src/java/org/apache/commons/math/stat/clustering/Clusterable.java @@ -1,46 +1,46 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.math.stat.clustering; - -import java.util.Collection; - -/** - * Interface for points that can be clustered together. - * @param the type of point that can be clustered - * @version $Revision$ $Date$ - * @since 2.0 - */ -public interface Clusterable { - - /** - * Returns the distance from the given point. - * - * @param p the point to compute the distance from - * @return the distance from the given point - */ - double distanceFrom(T p); - - /** - * Returns the centroid of the given Collection of points. - * - * @param p the Collection of points to compute the centroid of - * @return the centroid of the given Collection of Points - */ - T centroidOf(Collection p); - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.math.stat.clustering; + +import java.util.Collection; + +/** + * Interface for points that can be clustered together. + * @param the type of point that can be clustered + * @version $Revision$ $Date$ + * @since 2.0 + */ +public interface Clusterable { + + /** + * Returns the distance from the given point. + * + * @param p the point to compute the distance from + * @return the distance from the given point + */ + double distanceFrom(T p); + + /** + * Returns the centroid of the given Collection of points. + * + * @param p the Collection of points to compute the centroid of + * @return the centroid of the given Collection of Points + */ + T centroidOf(Collection p); + +} diff --git a/src/java/org/apache/commons/math/util/OpenIntToFieldHashMap.java b/src/java/org/apache/commons/math/util/OpenIntToFieldHashMap.java index fa03f2660..eb60d45e2 100644 --- a/src/java/org/apache/commons/math/util/OpenIntToFieldHashMap.java +++ b/src/java/org/apache/commons/math/util/OpenIntToFieldHashMap.java @@ -1,616 +1,616 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.lang.reflect.Array; -import java.util.ConcurrentModificationException; -import java.util.NoSuchElementException; - -import org.apache.commons.math.Field; -import org.apache.commons.math.FieldElement; -import org.apache.commons.math.MathRuntimeException; - -/** - * Open addressed map from int to FieldElement. - *

This class provides a dedicated map from integers to FieldElements with a - * much smaller memory overhead than standard java.util.Map.

- *

This class is not synchronized. The specialized iterators returned by - * {@link #iterator()} are fail-fast: they throw a - * ConcurrentModificationException when they detect the map has been - * modified during iteration.

- * @param the type of the field elements - * @version $Revision: 746578 $ $Date: 2009-02-21 12:01:14 -0800 (Sat, 21 Feb 2009) $ - * @since 2.0 - */ -public class OpenIntToFieldHashMap> implements Serializable { - - /** Serializable version identifier. */ - private static final long serialVersionUID = -9179080286849120720L; - - /** Load factor for the map. */ - private static final float LOAD_FACTOR = 0.5f; - - /** Default starting size. - *

This must be a power of two for bit mask to work properly.

- */ - private static final int DEFAULT_EXPECTED_SIZE = 16; - - /** Multiplier for size growth when map fills up. - *

This must be a power of two for bit mask to work properly.

- */ - private static final int RESIZE_MULTIPLIER = 2; - - /** Number of bits to perturb the index when probing for collision resolution. */ - private static final int PERTURB_SHIFT = 5; - - /** Status indicator for free table entries. */ - protected static final byte FREE = 0; - - /** Status indicator for full table entries. */ - protected static final byte FULL = 1; - - /** Status indicator for removed table entries. */ - protected static final byte REMOVED = 2; - - /** Field to which the elements belong. */ - private final Field field; - - /** Keys table. */ - private int[] keys; - - /** Values table. */ - private T[] values; - - /** States table. */ - private byte[] states; - - /** Return value for missing entries. */ - private final T missingEntries; - - /** Current size of the map. */ - private int size; - - /** Bit mask for hash values. */ - private int mask; - - /** Modifications count. */ - private transient int count; - - /** - * Build an empty map with default size and using zero for missing entries. - * @param field field to which the elements belong - */ - public OpenIntToFieldHashMap(final Fieldfield) { - this(field, DEFAULT_EXPECTED_SIZE, field.getZero()); - } - - /** - * Build an empty map with default size - * @param field field to which the elements belong - * @param missingEntries value to return when a missing entry is fetched - */ - public OpenIntToFieldHashMap(final Fieldfield, final T missingEntries) { - this(field,DEFAULT_EXPECTED_SIZE, missingEntries); - } - - /** - * Build an empty map with specified size and using zero for missing entries. - * @param field field to which the elements belong - * @param expectedSize expected number of elements in the map - */ - public OpenIntToFieldHashMap(final Field field,final int expectedSize) { - this(field,expectedSize, field.getZero()); - } - - /** - * Build an empty map with specified size. - * @param field field to which the elements belong - * @param expectedSize expected number of elements in the map - * @param missingEntries value to return when a missing entry is fetched - */ - public OpenIntToFieldHashMap(final Field field,final int expectedSize, - final T missingEntries) { - this.field = field; - final int capacity = computeCapacity(expectedSize); - keys = new int[capacity]; - values = buildArray(capacity); - states = new byte[capacity]; - this.missingEntries = missingEntries; - mask = capacity - 1; - } - - /** - * Copy constructor. - * @param source map to copy - */ - public OpenIntToFieldHashMap(final OpenIntToFieldHashMap source) { - field = source.field; - final int length = source.keys.length; - keys = new int[length]; - System.arraycopy(source.keys, 0, keys, 0, length); - values = buildArray(length); - System.arraycopy(source.values, 0, values, 0, length); - states = new byte[length]; - System.arraycopy(source.states, 0, states, 0, length); - missingEntries = source.missingEntries; - size = source.size; - mask = source.mask; - count = source.count; - } - - /** - * Compute the capacity needed for a given size. - * @param expectedSize expected size of the map - * @return capacity to use for the specified size - */ - private static int computeCapacity(final int expectedSize) { - if (expectedSize == 0) { - return 1; - } - final int capacity = (int) Math.ceil(expectedSize / LOAD_FACTOR); - final int powerOfTwo = Integer.highestOneBit(capacity); - if (powerOfTwo == capacity) { - return capacity; - } - return nextPowerOfTwo(capacity); - } - - /** - * Find the smallest power of two greater than the input value - * @param i input value - * @return smallest power of two greater than the input value - */ - private static int nextPowerOfTwo(final int i) { - return Integer.highestOneBit(i) << 1; - } - - /** - * Get the stored value associated with the given key - * @param key key associated with the data - * @return data associated with the key - */ - public T get(final int key) { - - final int hash = hashOf(key); - int index = hash & mask; - if (containsKey(key, index)) { - return values[index]; - } - - if (states[index] == FREE) { - return missingEntries; - } - - for (int perturb = perturb(hash), j = index; states[index] != FREE; perturb >>= PERTURB_SHIFT) { - j = probe(perturb, j); - index = j & mask; - if (containsKey(key, index)) { - return values[index]; - } - } - - return missingEntries; - - } - - /** - * Check if a value is associated with a key. - * @param key key to check - * @return true if a value is associated with key - */ - public boolean containsKey(final int key) { - - final int hash = hashOf(key); - int index = hash & mask; - if (containsKey(key, index)) { - return true; - } - - if (states[index] == FREE) { - return false; - } - - for (int perturb = perturb(hash), j = index; states[index] != FREE; perturb >>= PERTURB_SHIFT) { - j = probe(perturb, j); - index = j & mask; - if (containsKey(key, index)) { - return true; - } - } - - return false; - - } - - /** - * Get an iterator over map elements. - *

The specialized iterators returned are fail-fast: they throw a - * ConcurrentModificationException when they detect the map - * has been modified during iteration.

- * @return iterator over the map elements - */ - public Iterator iterator() { - return new Iterator(); - } - - /** - * Perturb the hash for starting probing. - * @param hash initial hash - * @return perturbed hash - */ - private static int perturb(final int hash) { - return hash & 0x7fffffff; - } - - /** - * Find the index at which a key should be inserted - * @param key key to lookup - * @return index at which key should be inserted - */ - private int findInsertionIndex(final int key) { - return findInsertionIndex(keys, states, key, mask); - } - - /** - * Find the index at which a key should be inserted - * @param keys keys table - * @param states states table - * @param key key to lookup - * @param mask bit mask for hash values - * @return index at which key should be inserted - */ - private static int findInsertionIndex(final int[] keys, final byte[] states, - final int key, final int mask) { - final int hash = hashOf(key); - int index = hash & mask; - if (states[index] == FREE) { - return index; - } else if (states[index] == FULL && keys[index] == key) { - return changeIndexSign(index); - } - - int perturb = perturb(hash); - int j = index; - if (states[index] == FULL) { - while (true) { - j = probe(perturb, j); - index = j & mask; - perturb >>= PERTURB_SHIFT; - - if (states[index] != FULL || keys[index] == key) { - break; - } - } - } - - if (states[index] == FREE) { - return index; - } else if (states[index] == FULL) { - // due to the loop exit condition, - // if (states[index] == FULL) then keys[index] == key - return changeIndexSign(index); - } - - final int firstRemoved = index; - while (true) { - j = probe(perturb, j); - index = j & mask; - - if (states[index] == FREE) { - return firstRemoved; - } else if (states[index] == FULL && keys[index] == key) { - return changeIndexSign(index); - } - - perturb >>= PERTURB_SHIFT; - - } - - } - - /** - * Compute next probe for collision resolution - * @param perturb perturbed hash - * @param j previous probe - * @return next probe - */ - private static int probe(final int perturb, final int j) { - return (j << 2) + j + perturb + 1; - } - - /** - * Change the index sign - * @param index initial index - * @return changed index - */ - private static int changeIndexSign(final int index) { - return -index - 1; - } - - /** - * Get the number of elements stored in the map. - * @return number of elements stored in the map - */ - public int size() { - return size; - } - - - /** - * Remove the value associated with a key. - * @param key key to which the value is associated - * @return removed value - */ - public T remove(final int key) { - - final int hash = hashOf(key); - int index = hash & mask; - if (containsKey(key, index)) { - return doRemove(index); - } - - if (states[index] == FREE) { - return missingEntries; - } - - for (int perturb = perturb(hash), j = index; states[index] != FREE; perturb >>= PERTURB_SHIFT) { - j = probe(perturb, j); - index = j & mask; - if (containsKey(key, index)) { - return doRemove(index); - } - } - - return missingEntries; - - } - - /** - * Check if the tables contain an element associated with specified key - * at specified index. - * @param key key to check - * @param index index to check - * @return true if an element is associated with key at index - */ - private boolean containsKey(final int key, final int index) { - return (key != 0 || states[index] == FULL) && keys[index] == key; - } - - /** - * Remove an element at specified index. - * @param index index of the element to remove - * @return removed value - */ - private T doRemove(int index) { - keys[index] = 0; - states[index] = REMOVED; - final T previous = values[index]; - values[index] = missingEntries; - --size; - ++count; - return previous; - } - - /** - * Put a value associated with a key in the map. - * @param key key to which value is associated - * @param value value to put in the map - * @return previous value associated with the key - */ - public T put(final int key, final T value) { - int index = findInsertionIndex(key); - T previous = missingEntries; - boolean newMapping = true; - if (index < 0) { - index = changeIndexSign(index); - previous = values[index]; - newMapping = false; - } - keys[index] = key; - states[index] = FULL; - values[index] = value; - if (newMapping) { - ++size; - if (shouldGrowTable()) { - growTable(); - } - ++count; - } - return previous; - - } - - /** - * Grow the tables. - */ - private void growTable() { - - final int oldLength = states.length; - final int[] oldKeys = keys; - final T[] oldValues = values; - final byte[] oldStates = states; - - final int newLength = RESIZE_MULTIPLIER * oldLength; - final int[] newKeys = new int[newLength]; - final T[] newValues = buildArray(newLength); - final byte[] newStates = new byte[newLength]; - final int newMask = newLength - 1; - for (int i = 0; i < oldLength; ++i) { - if (oldStates[i] == FULL) { - final int key = oldKeys[i]; - final int index = findInsertionIndex(newKeys, newStates, key, newMask); - newKeys[index] = key; - newValues[index] = oldValues[i]; - newStates[index] = FULL; - } - } - - mask = newMask; - keys = newKeys; - values = newValues; - states = newStates; - - } - - /** - * Check if tables should grow due to increased size. - * @return true if tables should grow - */ - private boolean shouldGrowTable() { - return size > (mask + 1) * LOAD_FACTOR; - } - - /** - * Compute the hash value of a key - * @param key key to hash - * @return hash value of the key - */ - private static int hashOf(final int key) { - final int h = key ^ ((key >>> 20) ^ (key >>> 12)); - return h ^ (h >>> 7) ^ (h >>> 4); - } - - - /** Iterator class for the map. */ - public class Iterator { - - /** Reference modification count. */ - private final int referenceCount; - - /** Index of current element. */ - private int current; - - /** Index of next element. */ - private int next; - - /** - * Simple constructor. - */ - private Iterator() { - - // preserve the modification count of the map to detect concurrent modifications later - referenceCount = count; - - // initialize current index - next = -1; - try { - advance(); - } catch (NoSuchElementException nsee) { - // ignored - } - - } - - /** - * Check if there is a next element in the map. - * @return true if there is a next element - */ - public boolean hasNext() { - return next >= 0; - } - - /** - * Get the key of current entry. - * @return key of current entry - * @exception ConcurrentModificationException if the map is modified during iteration - * @exception NoSuchElementException if there is no element left in the map - */ - public int key() - throws ConcurrentModificationException, NoSuchElementException { - if (referenceCount != count) { - throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating"); - } - if (current < 0) { - throw MathRuntimeException.createNoSuchElementException("iterator exhausted"); - } - return keys[current]; - } - - /** - * Get the value of current entry. - * @return value of current entry - * @exception ConcurrentModificationException if the map is modified during iteration - * @exception NoSuchElementException if there is no element left in the map - */ - public T value() - throws ConcurrentModificationException, NoSuchElementException { - if (referenceCount != count) { - throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating"); - } - if (current < 0) { - throw MathRuntimeException.createNoSuchElementException("iterator exhausted"); - } - return values[current]; - } - - /** - * Advance iterator one step further. - * @exception ConcurrentModificationException if the map is modified during iteration - * @exception NoSuchElementException if there is no element left in the map - */ - public void advance() - throws ConcurrentModificationException, NoSuchElementException { - - if (referenceCount != count) { - throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating"); - } - - // advance on step - current = next; - - // prepare next step - try { - while (states[++next] != FULL) { - // nothing to do - } - } catch (ArrayIndexOutOfBoundsException e) { - next = -2; - if (current < 0) { - throw MathRuntimeException.createNoSuchElementException("iterator exhausted"); - } - } - - } - - } - - /** - * Read a serialized object. - * @param stream input stream - * @throws IOException if object cannot be read - * @throws ClassNotFoundException if the class corresponding - * to the serialized object cannot be found - */ - private void readObject(final ObjectInputStream stream) - throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - count = 0; - } - - /** Build an array of elements. - * @param length size of the array to build - * @return a new array - */ - @SuppressWarnings("unchecked") - private T[] buildArray(final int length) { - return (T[]) Array.newInstance(field.getZero().getClass(), length); - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math.util; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.lang.reflect.Array; +import java.util.ConcurrentModificationException; +import java.util.NoSuchElementException; + +import org.apache.commons.math.Field; +import org.apache.commons.math.FieldElement; +import org.apache.commons.math.MathRuntimeException; + +/** + * Open addressed map from int to FieldElement. + *

This class provides a dedicated map from integers to FieldElements with a + * much smaller memory overhead than standard java.util.Map.

+ *

This class is not synchronized. The specialized iterators returned by + * {@link #iterator()} are fail-fast: they throw a + * ConcurrentModificationException when they detect the map has been + * modified during iteration.

+ * @param the type of the field elements + * @version $Revision: 746578 $ $Date: 2009-02-21 12:01:14 -0800 (Sat, 21 Feb 2009) $ + * @since 2.0 + */ +public class OpenIntToFieldHashMap> implements Serializable { + + /** Serializable version identifier. */ + private static final long serialVersionUID = -9179080286849120720L; + + /** Load factor for the map. */ + private static final float LOAD_FACTOR = 0.5f; + + /** Default starting size. + *

This must be a power of two for bit mask to work properly.

+ */ + private static final int DEFAULT_EXPECTED_SIZE = 16; + + /** Multiplier for size growth when map fills up. + *

This must be a power of two for bit mask to work properly.

+ */ + private static final int RESIZE_MULTIPLIER = 2; + + /** Number of bits to perturb the index when probing for collision resolution. */ + private static final int PERTURB_SHIFT = 5; + + /** Status indicator for free table entries. */ + protected static final byte FREE = 0; + + /** Status indicator for full table entries. */ + protected static final byte FULL = 1; + + /** Status indicator for removed table entries. */ + protected static final byte REMOVED = 2; + + /** Field to which the elements belong. */ + private final Field field; + + /** Keys table. */ + private int[] keys; + + /** Values table. */ + private T[] values; + + /** States table. */ + private byte[] states; + + /** Return value for missing entries. */ + private final T missingEntries; + + /** Current size of the map. */ + private int size; + + /** Bit mask for hash values. */ + private int mask; + + /** Modifications count. */ + private transient int count; + + /** + * Build an empty map with default size and using zero for missing entries. + * @param field field to which the elements belong + */ + public OpenIntToFieldHashMap(final Fieldfield) { + this(field, DEFAULT_EXPECTED_SIZE, field.getZero()); + } + + /** + * Build an empty map with default size + * @param field field to which the elements belong + * @param missingEntries value to return when a missing entry is fetched + */ + public OpenIntToFieldHashMap(final Fieldfield, final T missingEntries) { + this(field,DEFAULT_EXPECTED_SIZE, missingEntries); + } + + /** + * Build an empty map with specified size and using zero for missing entries. + * @param field field to which the elements belong + * @param expectedSize expected number of elements in the map + */ + public OpenIntToFieldHashMap(final Field field,final int expectedSize) { + this(field,expectedSize, field.getZero()); + } + + /** + * Build an empty map with specified size. + * @param field field to which the elements belong + * @param expectedSize expected number of elements in the map + * @param missingEntries value to return when a missing entry is fetched + */ + public OpenIntToFieldHashMap(final Field field,final int expectedSize, + final T missingEntries) { + this.field = field; + final int capacity = computeCapacity(expectedSize); + keys = new int[capacity]; + values = buildArray(capacity); + states = new byte[capacity]; + this.missingEntries = missingEntries; + mask = capacity - 1; + } + + /** + * Copy constructor. + * @param source map to copy + */ + public OpenIntToFieldHashMap(final OpenIntToFieldHashMap source) { + field = source.field; + final int length = source.keys.length; + keys = new int[length]; + System.arraycopy(source.keys, 0, keys, 0, length); + values = buildArray(length); + System.arraycopy(source.values, 0, values, 0, length); + states = new byte[length]; + System.arraycopy(source.states, 0, states, 0, length); + missingEntries = source.missingEntries; + size = source.size; + mask = source.mask; + count = source.count; + } + + /** + * Compute the capacity needed for a given size. + * @param expectedSize expected size of the map + * @return capacity to use for the specified size + */ + private static int computeCapacity(final int expectedSize) { + if (expectedSize == 0) { + return 1; + } + final int capacity = (int) Math.ceil(expectedSize / LOAD_FACTOR); + final int powerOfTwo = Integer.highestOneBit(capacity); + if (powerOfTwo == capacity) { + return capacity; + } + return nextPowerOfTwo(capacity); + } + + /** + * Find the smallest power of two greater than the input value + * @param i input value + * @return smallest power of two greater than the input value + */ + private static int nextPowerOfTwo(final int i) { + return Integer.highestOneBit(i) << 1; + } + + /** + * Get the stored value associated with the given key + * @param key key associated with the data + * @return data associated with the key + */ + public T get(final int key) { + + final int hash = hashOf(key); + int index = hash & mask; + if (containsKey(key, index)) { + return values[index]; + } + + if (states[index] == FREE) { + return missingEntries; + } + + for (int perturb = perturb(hash), j = index; states[index] != FREE; perturb >>= PERTURB_SHIFT) { + j = probe(perturb, j); + index = j & mask; + if (containsKey(key, index)) { + return values[index]; + } + } + + return missingEntries; + + } + + /** + * Check if a value is associated with a key. + * @param key key to check + * @return true if a value is associated with key + */ + public boolean containsKey(final int key) { + + final int hash = hashOf(key); + int index = hash & mask; + if (containsKey(key, index)) { + return true; + } + + if (states[index] == FREE) { + return false; + } + + for (int perturb = perturb(hash), j = index; states[index] != FREE; perturb >>= PERTURB_SHIFT) { + j = probe(perturb, j); + index = j & mask; + if (containsKey(key, index)) { + return true; + } + } + + return false; + + } + + /** + * Get an iterator over map elements. + *

The specialized iterators returned are fail-fast: they throw a + * ConcurrentModificationException when they detect the map + * has been modified during iteration.

+ * @return iterator over the map elements + */ + public Iterator iterator() { + return new Iterator(); + } + + /** + * Perturb the hash for starting probing. + * @param hash initial hash + * @return perturbed hash + */ + private static int perturb(final int hash) { + return hash & 0x7fffffff; + } + + /** + * Find the index at which a key should be inserted + * @param key key to lookup + * @return index at which key should be inserted + */ + private int findInsertionIndex(final int key) { + return findInsertionIndex(keys, states, key, mask); + } + + /** + * Find the index at which a key should be inserted + * @param keys keys table + * @param states states table + * @param key key to lookup + * @param mask bit mask for hash values + * @return index at which key should be inserted + */ + private static int findInsertionIndex(final int[] keys, final byte[] states, + final int key, final int mask) { + final int hash = hashOf(key); + int index = hash & mask; + if (states[index] == FREE) { + return index; + } else if (states[index] == FULL && keys[index] == key) { + return changeIndexSign(index); + } + + int perturb = perturb(hash); + int j = index; + if (states[index] == FULL) { + while (true) { + j = probe(perturb, j); + index = j & mask; + perturb >>= PERTURB_SHIFT; + + if (states[index] != FULL || keys[index] == key) { + break; + } + } + } + + if (states[index] == FREE) { + return index; + } else if (states[index] == FULL) { + // due to the loop exit condition, + // if (states[index] == FULL) then keys[index] == key + return changeIndexSign(index); + } + + final int firstRemoved = index; + while (true) { + j = probe(perturb, j); + index = j & mask; + + if (states[index] == FREE) { + return firstRemoved; + } else if (states[index] == FULL && keys[index] == key) { + return changeIndexSign(index); + } + + perturb >>= PERTURB_SHIFT; + + } + + } + + /** + * Compute next probe for collision resolution + * @param perturb perturbed hash + * @param j previous probe + * @return next probe + */ + private static int probe(final int perturb, final int j) { + return (j << 2) + j + perturb + 1; + } + + /** + * Change the index sign + * @param index initial index + * @return changed index + */ + private static int changeIndexSign(final int index) { + return -index - 1; + } + + /** + * Get the number of elements stored in the map. + * @return number of elements stored in the map + */ + public int size() { + return size; + } + + + /** + * Remove the value associated with a key. + * @param key key to which the value is associated + * @return removed value + */ + public T remove(final int key) { + + final int hash = hashOf(key); + int index = hash & mask; + if (containsKey(key, index)) { + return doRemove(index); + } + + if (states[index] == FREE) { + return missingEntries; + } + + for (int perturb = perturb(hash), j = index; states[index] != FREE; perturb >>= PERTURB_SHIFT) { + j = probe(perturb, j); + index = j & mask; + if (containsKey(key, index)) { + return doRemove(index); + } + } + + return missingEntries; + + } + + /** + * Check if the tables contain an element associated with specified key + * at specified index. + * @param key key to check + * @param index index to check + * @return true if an element is associated with key at index + */ + private boolean containsKey(final int key, final int index) { + return (key != 0 || states[index] == FULL) && keys[index] == key; + } + + /** + * Remove an element at specified index. + * @param index index of the element to remove + * @return removed value + */ + private T doRemove(int index) { + keys[index] = 0; + states[index] = REMOVED; + final T previous = values[index]; + values[index] = missingEntries; + --size; + ++count; + return previous; + } + + /** + * Put a value associated with a key in the map. + * @param key key to which value is associated + * @param value value to put in the map + * @return previous value associated with the key + */ + public T put(final int key, final T value) { + int index = findInsertionIndex(key); + T previous = missingEntries; + boolean newMapping = true; + if (index < 0) { + index = changeIndexSign(index); + previous = values[index]; + newMapping = false; + } + keys[index] = key; + states[index] = FULL; + values[index] = value; + if (newMapping) { + ++size; + if (shouldGrowTable()) { + growTable(); + } + ++count; + } + return previous; + + } + + /** + * Grow the tables. + */ + private void growTable() { + + final int oldLength = states.length; + final int[] oldKeys = keys; + final T[] oldValues = values; + final byte[] oldStates = states; + + final int newLength = RESIZE_MULTIPLIER * oldLength; + final int[] newKeys = new int[newLength]; + final T[] newValues = buildArray(newLength); + final byte[] newStates = new byte[newLength]; + final int newMask = newLength - 1; + for (int i = 0; i < oldLength; ++i) { + if (oldStates[i] == FULL) { + final int key = oldKeys[i]; + final int index = findInsertionIndex(newKeys, newStates, key, newMask); + newKeys[index] = key; + newValues[index] = oldValues[i]; + newStates[index] = FULL; + } + } + + mask = newMask; + keys = newKeys; + values = newValues; + states = newStates; + + } + + /** + * Check if tables should grow due to increased size. + * @return true if tables should grow + */ + private boolean shouldGrowTable() { + return size > (mask + 1) * LOAD_FACTOR; + } + + /** + * Compute the hash value of a key + * @param key key to hash + * @return hash value of the key + */ + private static int hashOf(final int key) { + final int h = key ^ ((key >>> 20) ^ (key >>> 12)); + return h ^ (h >>> 7) ^ (h >>> 4); + } + + + /** Iterator class for the map. */ + public class Iterator { + + /** Reference modification count. */ + private final int referenceCount; + + /** Index of current element. */ + private int current; + + /** Index of next element. */ + private int next; + + /** + * Simple constructor. + */ + private Iterator() { + + // preserve the modification count of the map to detect concurrent modifications later + referenceCount = count; + + // initialize current index + next = -1; + try { + advance(); + } catch (NoSuchElementException nsee) { + // ignored + } + + } + + /** + * Check if there is a next element in the map. + * @return true if there is a next element + */ + public boolean hasNext() { + return next >= 0; + } + + /** + * Get the key of current entry. + * @return key of current entry + * @exception ConcurrentModificationException if the map is modified during iteration + * @exception NoSuchElementException if there is no element left in the map + */ + public int key() + throws ConcurrentModificationException, NoSuchElementException { + if (referenceCount != count) { + throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating"); + } + if (current < 0) { + throw MathRuntimeException.createNoSuchElementException("iterator exhausted"); + } + return keys[current]; + } + + /** + * Get the value of current entry. + * @return value of current entry + * @exception ConcurrentModificationException if the map is modified during iteration + * @exception NoSuchElementException if there is no element left in the map + */ + public T value() + throws ConcurrentModificationException, NoSuchElementException { + if (referenceCount != count) { + throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating"); + } + if (current < 0) { + throw MathRuntimeException.createNoSuchElementException("iterator exhausted"); + } + return values[current]; + } + + /** + * Advance iterator one step further. + * @exception ConcurrentModificationException if the map is modified during iteration + * @exception NoSuchElementException if there is no element left in the map + */ + public void advance() + throws ConcurrentModificationException, NoSuchElementException { + + if (referenceCount != count) { + throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating"); + } + + // advance on step + current = next; + + // prepare next step + try { + while (states[++next] != FULL) { + // nothing to do + } + } catch (ArrayIndexOutOfBoundsException e) { + next = -2; + if (current < 0) { + throw MathRuntimeException.createNoSuchElementException("iterator exhausted"); + } + } + + } + + } + + /** + * Read a serialized object. + * @param stream input stream + * @throws IOException if object cannot be read + * @throws ClassNotFoundException if the class corresponding + * to the serialized object cannot be found + */ + private void readObject(final ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + count = 0; + } + + /** Build an array of elements. + * @param length size of the array to build + * @return a new array + */ + @SuppressWarnings("unchecked") + private T[] buildArray(final int length) { + return (T[]) Array.newInstance(field.getZero().getClass(), length); + } + +} diff --git a/src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java b/src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java old mode 100755 new mode 100644 diff --git a/src/test/org/apache/commons/math/linear/SparseFieldVectorTest.java b/src/test/org/apache/commons/math/linear/SparseFieldVectorTest.java index f1ac586e5..a92e902c2 100644 --- a/src/test/org/apache/commons/math/linear/SparseFieldVectorTest.java +++ b/src/test/org/apache/commons/math/linear/SparseFieldVectorTest.java @@ -1,218 +1,218 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math.linear; - - -import org.apache.commons.math.fraction.Fraction; -import org.apache.commons.math.fraction.FractionConversionException; -import org.apache.commons.math.fraction.FractionField; - - -import junit.framework.TestCase; - -/** - * Test cases for the {@link SparseFieldVector} class. - * - * @version $Revision: 728186 $ $Date: 2009-04-20 11:42:11 -0700 (Mon, 20 Apr 2009) $ - */ -public class SparseFieldVectorTest extends TestCase { - - // - protected Fraction[][] ma1 = {{new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)}, {new Fraction(7), new Fraction(8), new Fraction(9)}}; - protected Fraction[] vec1 = {new Fraction(1), new Fraction(2), new Fraction(3)}; - protected Fraction[] vec2 = {new Fraction(4), new Fraction(5), new Fraction(6)}; - protected Fraction[] vec3 = {new Fraction(7), new Fraction(8), new Fraction(9)}; - protected Fraction[] vec4 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8), new Fraction(9)}; - protected Fraction[] vec_null = {new Fraction(0), new Fraction(0), new Fraction(0)}; - protected Fraction[] dvec1 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8),new Fraction(9)}; - protected Fraction[][] mat1 = {{new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)},{ new Fraction(7), new Fraction(8), new Fraction(9)}}; - - // tolerances - protected double entryTolerance = 10E-16; - protected double normTolerance = 10E-14; - - protected FractionField field = FractionField.getInstance(); - - public void testMapFunctions() throws FractionConversionException { - SparseFieldVector v1 = new SparseFieldVector(field,vec1); - - //octave = v1 .+ 2.0 - FieldVector v_mapAdd = v1.mapAdd(new Fraction(2)); - Fraction[] result_mapAdd = {new Fraction(3), new Fraction(4), new Fraction(5)}; - assertEquals("compare vectors" ,result_mapAdd,v_mapAdd.getData()); - - //octave = v1 .+ 2.0 - FieldVector v_mapAddToSelf = v1.copy(); - v_mapAddToSelf.mapAddToSelf(new Fraction(2)); - Fraction[] result_mapAddToSelf = {new Fraction(3), new Fraction(4), new Fraction(5)}; - assertEquals("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.getData()); - - //octave = v1 .- 2.0 - FieldVector v_mapSubtract = v1.mapSubtract(new Fraction(2)); - Fraction[] result_mapSubtract = {new Fraction(-1), new Fraction(0), new Fraction(1)}; - assertEquals("compare vectors" ,result_mapSubtract,v_mapSubtract.getData()); - - //octave = v1 .- 2.0 - FieldVector v_mapSubtractToSelf = v1.copy(); - v_mapSubtractToSelf.mapSubtractToSelf(new Fraction(2)); - Fraction[] result_mapSubtractToSelf = {new Fraction(-1), new Fraction(0), new Fraction(1)}; - assertEquals("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.getData()); - - //octave = v1 .* 2.0 - FieldVector v_mapMultiply = v1.mapMultiply(new Fraction(2)); - Fraction[] result_mapMultiply = {new Fraction(2), new Fraction(4), new Fraction(6)}; - assertEquals("compare vectors" ,result_mapMultiply,v_mapMultiply.getData()); - - //octave = v1 .* 2.0 - FieldVector v_mapMultiplyToSelf = v1.copy(); - v_mapMultiplyToSelf.mapMultiplyToSelf(new Fraction(2)); - Fraction[] result_mapMultiplyToSelf = {new Fraction(2), new Fraction(4), new Fraction(6)}; - assertEquals("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.getData()); - - //octave = v1 ./ 2.0 - FieldVector v_mapDivide = v1.mapDivide(new Fraction(2)); - Fraction[] result_mapDivide = {new Fraction(.5d), new Fraction(1), new Fraction(1.5d)}; - assertEquals("compare vectors" ,result_mapDivide,v_mapDivide.getData()); - - //octave = v1 ./ 2.0 - FieldVector v_mapDivideToSelf = v1.copy(); - v_mapDivideToSelf.mapDivideToSelf(new Fraction(2)); - Fraction[] result_mapDivideToSelf = {new Fraction(.5d), new Fraction(1), new Fraction(1.5d)}; - assertEquals("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.getData()); - - //octave = v1 .^-1 - FieldVector v_mapInv = v1.mapInv(); - Fraction[] result_mapInv = {new Fraction(1),new Fraction(0.5d),new Fraction(3.333333333333333e-01d)}; - assertEquals("compare vectors" ,result_mapInv,v_mapInv.getData()); - - //octave = v1 .^-1 - FieldVector v_mapInvToSelf = v1.copy(); - v_mapInvToSelf.mapInvToSelf(); - Fraction[] result_mapInvToSelf = {new Fraction(1),new Fraction(0.5d),new Fraction(3.333333333333333e-01d)}; - assertEquals("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.getData()); - - - } - - public void testBasicFunctions() throws FractionConversionException { - SparseFieldVector v1 = new SparseFieldVector(field,vec1); - SparseFieldVector v2 = new SparseFieldVector(field,vec2); - - SparseFieldVector v2_t = new SparseFieldVector(field,vec2); - - //octave = v1 + v2 - FieldVector v_add = v1.add(v2); - Fraction[] result_add = {new Fraction(5), new Fraction(7), new Fraction(9)}; - assertEquals("compare vect" ,v_add.getData(),result_add); - - SparseFieldVector vt2 = new SparseFieldVector(field,vec2); - FieldVector v_add_i = v1.add(vt2); - Fraction[] result_add_i = {new Fraction(5), new Fraction(7), new Fraction(9)}; - assertEquals("compare vect" ,v_add_i.getData(),result_add_i); - - //octave = v1 - v2 - SparseFieldVector v_subtract = v1.subtract(v2); - Fraction[] result_subtract = {new Fraction(-3), new Fraction(-3), new Fraction(-3)}; - assertClose("compare vect" ,v_subtract.getData(),result_subtract,normTolerance); - - FieldVector v_subtract_i = v1.subtract(vt2); - Fraction[] result_subtract_i = {new Fraction(-3), new Fraction(-3), new Fraction(-3)}; - assertClose("compare vect" ,v_subtract_i.getData(),result_subtract_i,normTolerance); - - // octave v1 .* v2 - FieldVector v_ebeMultiply = v1.ebeMultiply(v2); - Fraction[] result_ebeMultiply = {new Fraction(4), new Fraction(10), new Fraction(18)}; - assertClose("compare vect" ,v_ebeMultiply.getData(),result_ebeMultiply,normTolerance); - - FieldVector v_ebeMultiply_2 = v1.ebeMultiply(v2_t); - Fraction[] result_ebeMultiply_2 = {new Fraction(4), new Fraction(10), new Fraction(18)}; - assertClose("compare vect" ,v_ebeMultiply_2.getData(),result_ebeMultiply_2,normTolerance); - - // octave v1 ./ v2 - FieldVector v_ebeDivide = v1.ebeDivide(v2); - Fraction[] result_ebeDivide = {new Fraction(0.25d), new Fraction(0.4d), new Fraction(0.5d)}; - assertClose("compare vect" ,v_ebeDivide.getData(),result_ebeDivide,normTolerance); - - FieldVector v_ebeDivide_2 = v1.ebeDivide(v2_t); - Fraction[] result_ebeDivide_2 = {new Fraction(0.25d), new Fraction(0.4d), new Fraction(0.5d)}; - assertClose("compare vect" ,v_ebeDivide_2.getData(),result_ebeDivide_2,normTolerance); - - // octave dot(v1,v2) - Fraction dot = v1.dotProduct(v2); - assertEquals("compare val ",new Fraction(32), dot); - - // octave dot(v1,v2_t) - Fraction dot_2 = v1.dotProduct(v2_t); - assertEquals("compare val ",new Fraction(32), dot_2); - - FieldMatrix m_outerProduct = v1.outerProduct(v2); - assertEquals("compare val ",new Fraction(4), m_outerProduct.getEntry(0,0)); - - FieldMatrix m_outerProduct_2 = v1.outerProduct(v2_t); - assertEquals("compare val ",new Fraction(4), m_outerProduct_2.getEntry(0,0)); - - } - - - public void testMisc() { - SparseFieldVector v1 = new SparseFieldVector(field,vec1); - - String out1 = v1.toString(); - assertTrue("some output ", out1.length()!=0); - try { - v1.checkVectorDimensions(2); - fail("IllegalArgumentException expected"); - } catch (IllegalArgumentException ex) { - // expected behavior - } catch (Exception e) { - fail("wrong exception caught"); - } - - - } - - public void testPredicates() { - - SparseFieldVector v = new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2) }); - - v.setEntry(0, field.getZero()); - assertEquals(v, new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2) })); - assertNotSame(v, new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2), new Fraction(3) })); - - } - - /** verifies that two vectors are close (sup norm) */ - protected void assertEquals(String msg, Fraction[] m, Fraction[] n) { - if (m.length != n.length) { - fail("vectors have different lengths"); - } - for (int i = 0; i < m.length; i++) { - assertEquals(msg + " " + i + " elements differ", m[i],n[i]); - } - } - - /** verifies that two vectors are close (sup norm) */ - protected void assertClose(String msg, Fraction[] m, Fraction[] n, double tolerance) { - if (m.length != n.length) { - fail("vectors have different lengths"); - } - for (int i = 0; i < m.length; i++) { - assertEquals(msg + " " + i + " elements differ", m[i].doubleValue(),n[i].doubleValue(), tolerance); - } - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math.linear; + + +import org.apache.commons.math.fraction.Fraction; +import org.apache.commons.math.fraction.FractionConversionException; +import org.apache.commons.math.fraction.FractionField; + + +import junit.framework.TestCase; + +/** + * Test cases for the {@link SparseFieldVector} class. + * + * @version $Revision: 728186 $ $Date: 2009-04-20 11:42:11 -0700 (Mon, 20 Apr 2009) $ + */ +public class SparseFieldVectorTest extends TestCase { + + // + protected Fraction[][] ma1 = {{new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)}, {new Fraction(7), new Fraction(8), new Fraction(9)}}; + protected Fraction[] vec1 = {new Fraction(1), new Fraction(2), new Fraction(3)}; + protected Fraction[] vec2 = {new Fraction(4), new Fraction(5), new Fraction(6)}; + protected Fraction[] vec3 = {new Fraction(7), new Fraction(8), new Fraction(9)}; + protected Fraction[] vec4 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8), new Fraction(9)}; + protected Fraction[] vec_null = {new Fraction(0), new Fraction(0), new Fraction(0)}; + protected Fraction[] dvec1 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8),new Fraction(9)}; + protected Fraction[][] mat1 = {{new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)},{ new Fraction(7), new Fraction(8), new Fraction(9)}}; + + // tolerances + protected double entryTolerance = 10E-16; + protected double normTolerance = 10E-14; + + protected FractionField field = FractionField.getInstance(); + + public void testMapFunctions() throws FractionConversionException { + SparseFieldVector v1 = new SparseFieldVector(field,vec1); + + //octave = v1 .+ 2.0 + FieldVector v_mapAdd = v1.mapAdd(new Fraction(2)); + Fraction[] result_mapAdd = {new Fraction(3), new Fraction(4), new Fraction(5)}; + assertEquals("compare vectors" ,result_mapAdd,v_mapAdd.getData()); + + //octave = v1 .+ 2.0 + FieldVector v_mapAddToSelf = v1.copy(); + v_mapAddToSelf.mapAddToSelf(new Fraction(2)); + Fraction[] result_mapAddToSelf = {new Fraction(3), new Fraction(4), new Fraction(5)}; + assertEquals("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.getData()); + + //octave = v1 .- 2.0 + FieldVector v_mapSubtract = v1.mapSubtract(new Fraction(2)); + Fraction[] result_mapSubtract = {new Fraction(-1), new Fraction(0), new Fraction(1)}; + assertEquals("compare vectors" ,result_mapSubtract,v_mapSubtract.getData()); + + //octave = v1 .- 2.0 + FieldVector v_mapSubtractToSelf = v1.copy(); + v_mapSubtractToSelf.mapSubtractToSelf(new Fraction(2)); + Fraction[] result_mapSubtractToSelf = {new Fraction(-1), new Fraction(0), new Fraction(1)}; + assertEquals("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.getData()); + + //octave = v1 .* 2.0 + FieldVector v_mapMultiply = v1.mapMultiply(new Fraction(2)); + Fraction[] result_mapMultiply = {new Fraction(2), new Fraction(4), new Fraction(6)}; + assertEquals("compare vectors" ,result_mapMultiply,v_mapMultiply.getData()); + + //octave = v1 .* 2.0 + FieldVector v_mapMultiplyToSelf = v1.copy(); + v_mapMultiplyToSelf.mapMultiplyToSelf(new Fraction(2)); + Fraction[] result_mapMultiplyToSelf = {new Fraction(2), new Fraction(4), new Fraction(6)}; + assertEquals("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.getData()); + + //octave = v1 ./ 2.0 + FieldVector v_mapDivide = v1.mapDivide(new Fraction(2)); + Fraction[] result_mapDivide = {new Fraction(.5d), new Fraction(1), new Fraction(1.5d)}; + assertEquals("compare vectors" ,result_mapDivide,v_mapDivide.getData()); + + //octave = v1 ./ 2.0 + FieldVector v_mapDivideToSelf = v1.copy(); + v_mapDivideToSelf.mapDivideToSelf(new Fraction(2)); + Fraction[] result_mapDivideToSelf = {new Fraction(.5d), new Fraction(1), new Fraction(1.5d)}; + assertEquals("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.getData()); + + //octave = v1 .^-1 + FieldVector v_mapInv = v1.mapInv(); + Fraction[] result_mapInv = {new Fraction(1),new Fraction(0.5d),new Fraction(3.333333333333333e-01d)}; + assertEquals("compare vectors" ,result_mapInv,v_mapInv.getData()); + + //octave = v1 .^-1 + FieldVector v_mapInvToSelf = v1.copy(); + v_mapInvToSelf.mapInvToSelf(); + Fraction[] result_mapInvToSelf = {new Fraction(1),new Fraction(0.5d),new Fraction(3.333333333333333e-01d)}; + assertEquals("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.getData()); + + + } + + public void testBasicFunctions() throws FractionConversionException { + SparseFieldVector v1 = new SparseFieldVector(field,vec1); + SparseFieldVector v2 = new SparseFieldVector(field,vec2); + + SparseFieldVector v2_t = new SparseFieldVector(field,vec2); + + //octave = v1 + v2 + FieldVector v_add = v1.add(v2); + Fraction[] result_add = {new Fraction(5), new Fraction(7), new Fraction(9)}; + assertEquals("compare vect" ,v_add.getData(),result_add); + + SparseFieldVector vt2 = new SparseFieldVector(field,vec2); + FieldVector v_add_i = v1.add(vt2); + Fraction[] result_add_i = {new Fraction(5), new Fraction(7), new Fraction(9)}; + assertEquals("compare vect" ,v_add_i.getData(),result_add_i); + + //octave = v1 - v2 + SparseFieldVector v_subtract = v1.subtract(v2); + Fraction[] result_subtract = {new Fraction(-3), new Fraction(-3), new Fraction(-3)}; + assertClose("compare vect" ,v_subtract.getData(),result_subtract,normTolerance); + + FieldVector v_subtract_i = v1.subtract(vt2); + Fraction[] result_subtract_i = {new Fraction(-3), new Fraction(-3), new Fraction(-3)}; + assertClose("compare vect" ,v_subtract_i.getData(),result_subtract_i,normTolerance); + + // octave v1 .* v2 + FieldVector v_ebeMultiply = v1.ebeMultiply(v2); + Fraction[] result_ebeMultiply = {new Fraction(4), new Fraction(10), new Fraction(18)}; + assertClose("compare vect" ,v_ebeMultiply.getData(),result_ebeMultiply,normTolerance); + + FieldVector v_ebeMultiply_2 = v1.ebeMultiply(v2_t); + Fraction[] result_ebeMultiply_2 = {new Fraction(4), new Fraction(10), new Fraction(18)}; + assertClose("compare vect" ,v_ebeMultiply_2.getData(),result_ebeMultiply_2,normTolerance); + + // octave v1 ./ v2 + FieldVector v_ebeDivide = v1.ebeDivide(v2); + Fraction[] result_ebeDivide = {new Fraction(0.25d), new Fraction(0.4d), new Fraction(0.5d)}; + assertClose("compare vect" ,v_ebeDivide.getData(),result_ebeDivide,normTolerance); + + FieldVector v_ebeDivide_2 = v1.ebeDivide(v2_t); + Fraction[] result_ebeDivide_2 = {new Fraction(0.25d), new Fraction(0.4d), new Fraction(0.5d)}; + assertClose("compare vect" ,v_ebeDivide_2.getData(),result_ebeDivide_2,normTolerance); + + // octave dot(v1,v2) + Fraction dot = v1.dotProduct(v2); + assertEquals("compare val ",new Fraction(32), dot); + + // octave dot(v1,v2_t) + Fraction dot_2 = v1.dotProduct(v2_t); + assertEquals("compare val ",new Fraction(32), dot_2); + + FieldMatrix m_outerProduct = v1.outerProduct(v2); + assertEquals("compare val ",new Fraction(4), m_outerProduct.getEntry(0,0)); + + FieldMatrix m_outerProduct_2 = v1.outerProduct(v2_t); + assertEquals("compare val ",new Fraction(4), m_outerProduct_2.getEntry(0,0)); + + } + + + public void testMisc() { + SparseFieldVector v1 = new SparseFieldVector(field,vec1); + + String out1 = v1.toString(); + assertTrue("some output ", out1.length()!=0); + try { + v1.checkVectorDimensions(2); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + + } + + public void testPredicates() { + + SparseFieldVector v = new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2) }); + + v.setEntry(0, field.getZero()); + assertEquals(v, new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2) })); + assertNotSame(v, new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2), new Fraction(3) })); + + } + + /** verifies that two vectors are close (sup norm) */ + protected void assertEquals(String msg, Fraction[] m, Fraction[] n) { + if (m.length != n.length) { + fail("vectors have different lengths"); + } + for (int i = 0; i < m.length; i++) { + assertEquals(msg + " " + i + " elements differ", m[i],n[i]); + } + } + + /** verifies that two vectors are close (sup norm) */ + protected void assertClose(String msg, Fraction[] m, Fraction[] n, double tolerance) { + if (m.length != n.length) { + fail("vectors have different lengths"); + } + for (int i = 0; i < m.length; i++) { + assertEquals(msg + " " + i + " elements differ", m[i].doubleValue(),n[i].doubleValue(), tolerance); + } + } + +}