http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/common/RandomUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/common/RandomUtils.java b/core/src/main/java/org/apache/mahout/common/RandomUtils.java deleted file mode 100644 index ba71292..0000000 --- a/core/src/main/java/org/apache/mahout/common/RandomUtils.java +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 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.mahout.common; - -import java.util.Collections; -import java.util.Map; -import java.util.Random; -import java.util.WeakHashMap; - -import com.google.common.primitives.Longs; -import org.apache.commons.math3.primes.Primes; - -/** - * <p> - * The source of random stuff for the whole project. This lets us make all randomness in the project - * predictable, if desired, for when we run unit tests, which should be repeatable. - * </p> - */ -public final class RandomUtils { - - /** The largest prime less than 2<sup>31</sup>-1 that is the smaller of a twin prime pair. */ - public static final int MAX_INT_SMALLER_TWIN_PRIME = 2147482949; - - private static final Map<RandomWrapper,Boolean> INSTANCES = - Collections.synchronizedMap(new WeakHashMap<RandomWrapper,Boolean>()); - - private static boolean testSeed = false; - - private RandomUtils() { } - - public static void useTestSeed() { - testSeed = true; - synchronized (INSTANCES) { - for (RandomWrapper rng : INSTANCES.keySet()) { - rng.resetToTestSeed(); - } - } - } - - public static RandomWrapper getRandom() { - RandomWrapper random = new RandomWrapper(); - if (testSeed) { - random.resetToTestSeed(); - } - INSTANCES.put(random, Boolean.TRUE); - return random; - } - - public static Random getRandom(long seed) { - RandomWrapper random = new RandomWrapper(seed); - INSTANCES.put(random, Boolean.TRUE); - return random; - } - - /** @return what {@link Double#hashCode()} would return for the same value */ - public static int hashDouble(double value) { - return Longs.hashCode(Double.doubleToLongBits(value)); - } - - /** @return what {@link Float#hashCode()} would return for the same value */ - public static int hashFloat(float value) { - return Float.floatToIntBits(value); - } - - /** - * <p> - * Finds next-largest "twin primes": numbers p and p+2 such that both are prime. Finds the smallest such p - * such that the smaller twin, p, is greater than or equal to n. Returns p+2, the larger of the two twins. - * </p> - */ - public static int nextTwinPrime(int n) { - if (n > MAX_INT_SMALLER_TWIN_PRIME) { - throw new IllegalArgumentException(); - } - if (n <= 3) { - return 5; - } - int next = Primes.nextPrime(n); - while (!Primes.isPrime(next + 2)) { - next = Primes.nextPrime(next + 4); - } - return next + 2; - } - -}
http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/common/RandomWrapper.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/common/RandomWrapper.java b/core/src/main/java/org/apache/mahout/common/RandomWrapper.java deleted file mode 100644 index 802291b..0000000 --- a/core/src/main/java/org/apache/mahout/common/RandomWrapper.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * 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.mahout.common; - -import org.apache.commons.math3.random.MersenneTwister; -import org.apache.commons.math3.random.RandomGenerator; - -import java.util.Random; - -public final class RandomWrapper extends Random { - - private static final long STANDARD_SEED = 0xCAFEDEADBEEFBABEL; - - private final RandomGenerator random; - - RandomWrapper() { - random = new MersenneTwister(); - random.setSeed(System.currentTimeMillis() + System.identityHashCode(random)); - } - - RandomWrapper(long seed) { - random = new MersenneTwister(seed); - } - - @Override - public void setSeed(long seed) { - // Since this will be called by the java.util.Random() constructor before we construct - // the delegate... and because we don't actually care about the result of this for our - // purpose: - if (random != null) { - random.setSeed(seed); - } - } - - void resetToTestSeed() { - setSeed(STANDARD_SEED); - } - - public RandomGenerator getRandomGenerator() { - return random; - } - - @Override - protected int next(int bits) { - // Ugh, can't delegate this method -- it's protected - // Callers can't use it and other methods are delegated, so shouldn't matter - throw new UnsupportedOperationException(); - } - - @Override - public void nextBytes(byte[] bytes) { - random.nextBytes(bytes); - } - - @Override - public int nextInt() { - return random.nextInt(); - } - - @Override - public int nextInt(int n) { - return random.nextInt(n); - } - - @Override - public long nextLong() { - return random.nextLong(); - } - - @Override - public boolean nextBoolean() { - return random.nextBoolean(); - } - - @Override - public float nextFloat() { - return random.nextFloat(); - } - - @Override - public double nextDouble() { - return random.nextDouble(); - } - - @Override - public double nextGaussian() { - return random.nextGaussian(); - } - -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/AbstractMatrix.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/AbstractMatrix.java b/core/src/main/java/org/apache/mahout/math/AbstractMatrix.java deleted file mode 100644 index eaaa397..0000000 --- a/core/src/main/java/org/apache/mahout/math/AbstractMatrix.java +++ /dev/null @@ -1,834 +0,0 @@ -/* - * 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.mahout.math; - -import com.google.common.collect.AbstractIterator; -import com.google.common.collect.Maps; -import org.apache.mahout.math.flavor.MatrixFlavor; -import org.apache.mahout.math.function.DoubleDoubleFunction; -import org.apache.mahout.math.function.DoubleFunction; -import org.apache.mahout.math.function.Functions; -import org.apache.mahout.math.function.PlusMult; -import org.apache.mahout.math.function.VectorFunction; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * A few universal implementations of convenience functions for a JVM-backed matrix. - */ -public abstract class AbstractMatrix implements Matrix { - - protected Map<String, Integer> columnLabelBindings; - protected Map<String, Integer> rowLabelBindings; - protected int rows; - protected int columns; - - protected AbstractMatrix(int rows, int columns) { - this.rows = rows; - this.columns = columns; - } - - @Override - public int columnSize() { - return columns; - } - - @Override - public int rowSize() { - return rows; - } - - @Override - public Iterator<MatrixSlice> iterator() { - return iterateAll(); - } - - @Override - public Iterator<MatrixSlice> iterateAll() { - return new AbstractIterator<MatrixSlice>() { - private int row; - - @Override - protected MatrixSlice computeNext() { - if (row >= numRows()) { - return endOfData(); - } - int i = row++; - return new MatrixSlice(viewRow(i), i); - } - }; - } - - @Override - public Iterator<MatrixSlice> iterateNonEmpty() { - return iterator(); - } - - /** - * Abstracted out for the iterator - * - * @return numRows() for row-based iterator, numColumns() for column-based. - */ - @Override - public int numSlices() { - return numRows(); - } - - @Override - public double get(String rowLabel, String columnLabel) { - if (columnLabelBindings == null || rowLabelBindings == null) { - throw new IllegalStateException("Unbound label"); - } - Integer row = rowLabelBindings.get(rowLabel); - Integer col = columnLabelBindings.get(columnLabel); - if (row == null || col == null) { - throw new IllegalStateException("Unbound label"); - } - - return get(row, col); - } - - @Override - public Map<String, Integer> getColumnLabelBindings() { - return columnLabelBindings; - } - - @Override - public Map<String, Integer> getRowLabelBindings() { - return rowLabelBindings; - } - - @Override - public void set(String rowLabel, double[] rowData) { - if (columnLabelBindings == null) { - throw new IllegalStateException("Unbound label"); - } - Integer row = rowLabelBindings.get(rowLabel); - if (row == null) { - throw new IllegalStateException("Unbound label"); - } - set(row, rowData); - } - - @Override - public void set(String rowLabel, int row, double[] rowData) { - if (rowLabelBindings == null) { - rowLabelBindings = new HashMap<>(); - } - rowLabelBindings.put(rowLabel, row); - set(row, rowData); - } - - @Override - public void set(String rowLabel, String columnLabel, double value) { - if (columnLabelBindings == null || rowLabelBindings == null) { - throw new IllegalStateException("Unbound label"); - } - Integer row = rowLabelBindings.get(rowLabel); - Integer col = columnLabelBindings.get(columnLabel); - if (row == null || col == null) { - throw new IllegalStateException("Unbound label"); - } - set(row, col, value); - } - - @Override - public void set(String rowLabel, String columnLabel, int row, int column, double value) { - if (rowLabelBindings == null) { - rowLabelBindings = new HashMap<>(); - } - rowLabelBindings.put(rowLabel, row); - if (columnLabelBindings == null) { - columnLabelBindings = new HashMap<>(); - } - columnLabelBindings.put(columnLabel, column); - - set(row, column, value); - } - - @Override - public void setColumnLabelBindings(Map<String, Integer> bindings) { - columnLabelBindings = bindings; - } - - @Override - public void setRowLabelBindings(Map<String, Integer> bindings) { - rowLabelBindings = bindings; - } - - // index into int[2] for column value - public static final int COL = 1; - - // index into int[2] for row value - public static final int ROW = 0; - - @Override - public int numRows() { - return rowSize(); - } - - @Override - public int numCols() { - return columnSize(); - } - - @Override - public String asFormatString() { - return toString(); - } - - @Override - public Matrix assign(double value) { - int rows = rowSize(); - int columns = columnSize(); - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - setQuick(row, col, value); - } - } - return this; - } - - @Override - public Matrix assign(double[][] values) { - int rows = rowSize(); - if (rows != values.length) { - throw new CardinalityException(rows, values.length); - } - int columns = columnSize(); - for (int row = 0; row < rows; row++) { - if (columns == values[row].length) { - for (int col = 0; col < columns; col++) { - setQuick(row, col, values[row][col]); - } - } else { - throw new CardinalityException(columns, values[row].length); - } - } - return this; - } - - @Override - public Matrix assign(Matrix other, DoubleDoubleFunction function) { - int rows = rowSize(); - if (rows != other.rowSize()) { - throw new CardinalityException(rows, other.rowSize()); - } - int columns = columnSize(); - if (columns != other.columnSize()) { - throw new CardinalityException(columns, other.columnSize()); - } - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - setQuick(row, col, function.apply(getQuick(row, col), other.getQuick( - row, col))); - } - } - return this; - } - - @Override - public Matrix assign(Matrix other) { - int rows = rowSize(); - if (rows != other.rowSize()) { - throw new CardinalityException(rows, other.rowSize()); - } - int columns = columnSize(); - if (columns != other.columnSize()) { - throw new CardinalityException(columns, other.columnSize()); - } - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - setQuick(row, col, other.getQuick(row, col)); - } - } - return this; - } - - @Override - public Matrix assign(DoubleFunction function) { - int rows = rowSize(); - int columns = columnSize(); - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - setQuick(row, col, function.apply(getQuick(row, col))); - } - } - return this; - } - - /** - * Collects the results of a function applied to each row of a matrix. - * - * @param f The function to be applied to each row. - * @return The vector of results. - */ - @Override - public Vector aggregateRows(VectorFunction f) { - Vector r = new DenseVector(numRows()); - int n = numRows(); - for (int row = 0; row < n; row++) { - r.set(row, f.apply(viewRow(row))); - } - return r; - } - - /** - * Returns a view of a row. Changes to the view will affect the original. - * - * @param row Which row to return. - * @return A vector that references the desired row. - */ - @Override - public Vector viewRow(int row) { - return new MatrixVectorView(this, row, 0, 0, 1); - } - - - /** - * Returns a view of a row. Changes to the view will affect the original. - * - * @param column Which column to return. - * @return A vector that references the desired column. - */ - @Override - public Vector viewColumn(int column) { - return new MatrixVectorView(this, 0, column, 1, 0); - } - - /** - * Provides a view of the diagonal of a matrix. - */ - @Override - public Vector viewDiagonal() { - return new MatrixVectorView(this, 0, 0, 1, 1); - } - - /** - * Collects the results of a function applied to each element of a matrix and then aggregated. - * - * @param combiner A function that combines the results of the mapper. - * @param mapper A function to apply to each element. - * @return The result. - */ - @Override - public double aggregate(final DoubleDoubleFunction combiner, final DoubleFunction mapper) { - return aggregateRows(new VectorFunction() { - @Override - public double apply(Vector v) { - return v.aggregate(combiner, mapper); - } - }).aggregate(combiner, Functions.IDENTITY); - } - - /** - * Collects the results of a function applied to each column of a matrix. - * - * @param f The function to be applied to each column. - * @return The vector of results. - */ - @Override - public Vector aggregateColumns(VectorFunction f) { - Vector r = new DenseVector(numCols()); - for (int col = 0; col < numCols(); col++) { - r.set(col, f.apply(viewColumn(col))); - } - return r; - } - - @Override - public double determinant() { - int rows = rowSize(); - int columns = columnSize(); - if (rows != columns) { - throw new CardinalityException(rows, columns); - } - - if (rows == 2) { - return getQuick(0, 0) * getQuick(1, 1) - getQuick(0, 1) * getQuick(1, 0); - } else { - // TODO: this really should just be one line: - // TODO: new CholeskyDecomposition(this).getL().viewDiagonal().aggregate(Functions.TIMES) - int sign = 1; - double ret = 0; - - for (int i = 0; i < columns; i++) { - Matrix minor = new DenseMatrix(rows - 1, columns - 1); - for (int j = 1; j < rows; j++) { - boolean flag = false; /* column offset flag */ - for (int k = 0; k < columns; k++) { - if (k == i) { - flag = true; - continue; - } - minor.set(j - 1, flag ? k - 1 : k, getQuick(j, k)); - } - } - ret += getQuick(0, i) * sign * minor.determinant(); - sign *= -1; - - } - - return ret; - } - - } - - @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException") - @Override - public Matrix clone() { - AbstractMatrix clone; - try { - clone = (AbstractMatrix) super.clone(); - } catch (CloneNotSupportedException cnse) { - throw new IllegalStateException(cnse); // can't happen - } - if (rowLabelBindings != null) { - clone.rowLabelBindings = Maps.newHashMap(rowLabelBindings); - } - if (columnLabelBindings != null) { - clone.columnLabelBindings = Maps.newHashMap(columnLabelBindings); - } - return clone; - } - - @Override - public Matrix divide(double x) { - Matrix result = like(); - for (int row = 0; row < rowSize(); row++) { - for (int col = 0; col < columnSize(); col++) { - result.setQuick(row, col, getQuick(row, col) / x); - } - } - return result; - } - - @Override - public double get(int row, int column) { - if (row < 0 || row >= rowSize()) { - throw new IndexException(row, rowSize()); - } - if (column < 0 || column >= columnSize()) { - throw new IndexException(column, columnSize()); - } - return getQuick(row, column); - } - - @Override - public Matrix minus(Matrix other) { - int rows = rowSize(); - if (rows != other.rowSize()) { - throw new CardinalityException(rows, other.rowSize()); - } - int columns = columnSize(); - if (columns != other.columnSize()) { - throw new CardinalityException(columns, other.columnSize()); - } - Matrix result = like(); - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - result.setQuick(row, col, getQuick(row, col) - - other.getQuick(row, col)); - } - } - return result; - } - - @Override - public Matrix plus(double x) { - Matrix result = like(); - int rows = rowSize(); - int columns = columnSize(); - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - result.setQuick(row, col, getQuick(row, col) + x); - } - } - return result; - } - - @Override - public Matrix plus(Matrix other) { - int rows = rowSize(); - if (rows != other.rowSize()) { - throw new CardinalityException(rows, other.rowSize()); - } - int columns = columnSize(); - if (columns != other.columnSize()) { - throw new CardinalityException(columns, other.columnSize()); - } - Matrix result = like(); - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - result.setQuick(row, col, getQuick(row, col) - + other.getQuick(row, col)); - } - } - return result; - } - - @Override - public void set(int row, int column, double value) { - if (row < 0 || row >= rowSize()) { - throw new IndexException(row, rowSize()); - } - if (column < 0 || column >= columnSize()) { - throw new IndexException(column, columnSize()); - } - setQuick(row, column, value); - } - - @Override - public void set(int row, double[] data) { - int columns = columnSize(); - if (columns < data.length) { - throw new CardinalityException(columns, data.length); - } - int rows = rowSize(); - if (row < 0 || row >= rows) { - throw new IndexException(row, rowSize()); - } - for (int i = 0; i < columns; i++) { - setQuick(row, i, data[i]); - } - } - - @Override - public Matrix times(double x) { - Matrix result = like(); - int rows = rowSize(); - int columns = columnSize(); - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - result.setQuick(row, col, getQuick(row, col) * x); - } - } - return result; - } - - @Override - public Matrix times(Matrix other) { - int columns = columnSize(); - if (columns != other.rowSize()) { - throw new CardinalityException(columns, other.rowSize()); - } - int rows = rowSize(); - int otherColumns = other.columnSize(); - Matrix result = like(rows, otherColumns); - for (int row = 0; row < rows; row++) { - for (int col = 0; col < otherColumns; col++) { - double sum = 0.0; - for (int k = 0; k < columns; k++) { - sum += getQuick(row, k) * other.getQuick(k, col); - } - result.setQuick(row, col, sum); - } - } - return result; - } - - @Override - public Vector times(Vector v) { - int columns = columnSize(); - if (columns != v.size()) { - throw new CardinalityException(columns, v.size()); - } - int rows = rowSize(); - Vector w = new DenseVector(rows); - for (int row = 0; row < rows; row++) { - w.setQuick(row, v.dot(viewRow(row))); - } - return w; - } - - @Override - public Vector timesSquared(Vector v) { - int columns = columnSize(); - if (columns != v.size()) { - throw new CardinalityException(columns, v.size()); - } - int rows = rowSize(); - Vector w = new DenseVector(columns); - for (int i = 0; i < rows; i++) { - Vector xi = viewRow(i); - double d = xi.dot(v); - if (d != 0.0) { - w.assign(xi, new PlusMult(d)); - } - - } - return w; - } - - @Override - public Matrix transpose() { - int rows = rowSize(); - int columns = columnSize(); - Matrix result = like(columns, rows); - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - result.setQuick(col, row, getQuick(row, col)); - } - } - return result; - } - - @Override - public Matrix viewPart(int rowOffset, int rowsRequested, int columnOffset, int columnsRequested) { - return viewPart(new int[]{rowOffset, columnOffset}, new int[]{rowsRequested, columnsRequested}); - } - - @Override - public Matrix viewPart(int[] offset, int[] size) { - - if (offset[ROW] < 0) { - throw new IndexException(offset[ROW], 0); - } - if (offset[ROW] + size[ROW] > rowSize()) { - throw new IndexException(offset[ROW] + size[ROW], rowSize()); - } - if (offset[COL] < 0) { - throw new IndexException(offset[COL], 0); - } - if (offset[COL] + size[COL] > columnSize()) { - throw new IndexException(offset[COL] + size[COL], columnSize()); - } - - return new MatrixView(this, offset, size); - } - - - @Override - public double zSum() { - double result = 0; - for (int row = 0; row < rowSize(); row++) { - for (int col = 0; col < columnSize(); col++) { - result += getQuick(row, col); - } - } - return result; - } - - @Override - public int[] getNumNondefaultElements() { - return new int[]{rowSize(), columnSize()}; - } - - protected static class TransposeViewVector extends AbstractVector { - - private final Matrix matrix; - private final int transposeOffset; - private final int numCols; - private final boolean rowToColumn; - - protected TransposeViewVector(Matrix m, int offset) { - this(m, offset, true); - } - - protected TransposeViewVector(Matrix m, int offset, boolean rowToColumn) { - super(rowToColumn ? m.numRows() : m.numCols()); - matrix = m; - this.transposeOffset = offset; - this.rowToColumn = rowToColumn; - numCols = rowToColumn ? m.numCols() : m.numRows(); - } - - @SuppressWarnings("CloneDoesntCallSuperClone") - @Override - public Vector clone() { - Vector v = new DenseVector(size()); - v.assign(this, Functions.PLUS); - return v; - } - - @Override - public boolean isDense() { - return true; - } - - @Override - public boolean isSequentialAccess() { - return true; - } - - @Override - protected Matrix matrixLike(int rows, int columns) { - return matrix.like(rows, columns); - } - - @Override - public Iterator<Element> iterator() { - return new AbstractIterator<Element>() { - private int i; - - @Override - protected Element computeNext() { - if (i >= size()) { - return endOfData(); - } - return getElement(i++); - } - }; - } - - /** - * Currently delegates to {@link #iterator()}. - * TODO: This could be optimized to at least skip empty rows if there are many of them. - * - * @return an iterator (currently dense). - */ - @Override - public Iterator<Element> iterateNonZero() { - return iterator(); - } - - @Override - public Element getElement(final int i) { - return new Element() { - @Override - public double get() { - return getQuick(i); - } - - @Override - public int index() { - return i; - } - - @Override - public void set(double value) { - setQuick(i, value); - } - }; - } - - /** - * Used internally by assign() to update multiple indices and values at once. - * Only really useful for sparse vectors (especially SequentialAccessSparseVector). - * <p> - * If someone ever adds a new type of sparse vectors, this method must merge (index, value) pairs into the vector. - * - * @param updates a mapping of indices to values to merge in the vector. - */ - @Override - public void mergeUpdates(OrderedIntDoubleMapping updates) { - throw new UnsupportedOperationException("Cannot mutate TransposeViewVector"); - } - - @Override - public double getQuick(int index) { - Vector v = rowToColumn ? matrix.viewColumn(index) : matrix.viewRow(index); - return v == null ? 0.0 : v.getQuick(transposeOffset); - } - - @Override - public void setQuick(int index, double value) { - Vector v = rowToColumn ? matrix.viewColumn(index) : matrix.viewRow(index); - if (v == null) { - v = newVector(numCols); - if (rowToColumn) { - matrix.assignColumn(index, v); - } else { - matrix.assignRow(index, v); - } - } - v.setQuick(transposeOffset, value); - } - - protected Vector newVector(int cardinality) { - return new DenseVector(cardinality); - } - - @Override - public Vector like() { - return new DenseVector(size()); - } - - public Vector like(int cardinality) { - return new DenseVector(cardinality); - } - - /** - * TODO: currently I don't know of an efficient way to getVector this value correctly. - * - * @return the number of nonzero entries - */ - @Override - public int getNumNondefaultElements() { - return size(); - } - - @Override - public double getLookupCost() { - return (rowToColumn ? matrix.viewColumn(0) : matrix.viewRow(0)).getLookupCost(); - } - - @Override - public double getIteratorAdvanceCost() { - return (rowToColumn ? matrix.viewColumn(0) : matrix.viewRow(0)).getIteratorAdvanceCost(); - } - - @Override - public boolean isAddConstantTime() { - return (rowToColumn ? matrix.viewColumn(0) : matrix.viewRow(0)).isAddConstantTime(); - } - } - - @Override - public String toString() { - int row = 0; - int maxRowsToDisplay = 10; - int maxColsToDisplay = 20; - int colsToDisplay = maxColsToDisplay; - - if(maxColsToDisplay > columnSize()){ - colsToDisplay = columnSize(); - } - - - StringBuilder s = new StringBuilder("{\n"); - Iterator<MatrixSlice> it = iterator(); - while ((it.hasNext()) && (row < maxRowsToDisplay)) { - MatrixSlice next = it.next(); - s.append(" ").append(next.index()) - .append(" =>\t") - .append(new VectorView(next.vector(), 0, colsToDisplay)) - .append('\n'); - row ++; - } - String returnString = s.toString(); - if (maxColsToDisplay <= columnSize()) { - returnString = returnString.replace("}", " ... } "); - } - if(maxRowsToDisplay <= rowSize()) - return returnString + ("... }"); - else{ - return returnString + ("}"); - } - } - - @Override - public MatrixFlavor getFlavor() { - throw new UnsupportedOperationException("Flavor support not implemented for this matrix."); - } - - ////////////// Matrix flavor trait /////////////////// - -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/AbstractVector.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/AbstractVector.java b/core/src/main/java/org/apache/mahout/math/AbstractVector.java deleted file mode 100644 index 27eddbc..0000000 --- a/core/src/main/java/org/apache/mahout/math/AbstractVector.java +++ /dev/null @@ -1,684 +0,0 @@ -/* - * 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.mahout.math; - -import java.util.Iterator; - -import com.google.common.base.Preconditions; -import org.apache.mahout.common.RandomUtils; -import org.apache.mahout.math.function.DoubleDoubleFunction; -import org.apache.mahout.math.function.DoubleFunction; -import org.apache.mahout.math.function.Functions; - -/** Implementations of generic capabilities like sum of elements and dot products */ -public abstract class AbstractVector implements Vector, LengthCachingVector { - - private int size; - protected double lengthSquared = -1.0; - - protected AbstractVector(int size) { - this.size = size; - } - - @Override - public Iterable<Element> all() { - return new Iterable<Element>() { - @Override - public Iterator<Element> iterator() { - return AbstractVector.this.iterator(); - } - }; - } - - @Override - public Iterable<Element> nonZeroes() { - return new Iterable<Element>() { - @Override - public Iterator<Element> iterator() { - return iterateNonZero(); - } - }; - } - - /** - * Iterates over all elements <p> - * NOTE: Implementations may choose to reuse the Element returned for performance - * reasons, so if you need a copy of it, you should call {@link #getElement(int)} for the given index - * - * @return An {@link Iterator} over all elements - */ - protected abstract Iterator<Element> iterator(); - - /** - * Iterates over all non-zero elements. <p> - * NOTE: Implementations may choose to reuse the Element returned for - * performance reasons, so if you need a copy of it, you should call {@link #getElement(int)} for the given index - * - * @return An {@link Iterator} over all non-zero elements - */ - protected abstract Iterator<Element> iterateNonZero(); - /** - * Aggregates a vector by applying a mapping function fm(x) to every component and aggregating - * the results with an aggregating function fa(x, y). - * - * @param aggregator used to combine the current value of the aggregation with the result of map.apply(nextValue) - * @param map a function to apply to each element of the vector in turn before passing to the aggregator - * @return the result of the aggregation - */ - @Override - public double aggregate(DoubleDoubleFunction aggregator, DoubleFunction map) { - if (size == 0) { - return 0; - } - - // If the aggregator is associative and commutative and it's likeLeftMult (fa(0, y) = 0), and there is - // at least one zero in the vector (size > getNumNondefaultElements) and applying fm(0) = 0, the result - // gets cascaded through the aggregation and the final result will be 0. - if (aggregator.isAssociativeAndCommutative() && aggregator.isLikeLeftMult() - && size > getNumNondefaultElements() && !map.isDensifying()) { - return 0; - } - - double result; - if (isSequentialAccess() || aggregator.isAssociativeAndCommutative()) { - Iterator<Element> iterator; - // If fm(0) = 0 and fa(x, 0) = x, we can skip all zero values. - if (!map.isDensifying() && aggregator.isLikeRightPlus()) { - iterator = iterateNonZero(); - if (!iterator.hasNext()) { - return 0; - } - } else { - iterator = iterator(); - } - Element element = iterator.next(); - result = map.apply(element.get()); - while (iterator.hasNext()) { - element = iterator.next(); - result = aggregator.apply(result, map.apply(element.get())); - } - } else { - result = map.apply(getQuick(0)); - for (int i = 1; i < size; i++) { - result = aggregator.apply(result, map.apply(getQuick(i))); - } - } - - return result; - } - - @Override - public double aggregate(Vector other, DoubleDoubleFunction aggregator, DoubleDoubleFunction combiner) { - Preconditions.checkArgument(size == other.size(), "Vector sizes differ"); - if (size == 0) { - return 0; - } - return VectorBinaryAggregate.aggregateBest(this, other, aggregator, combiner); - } - - /** - * Subclasses must override to return an appropriately sparse or dense result - * - * @param rows the row cardinality - * @param columns the column cardinality - * @return a Matrix - */ - protected abstract Matrix matrixLike(int rows, int columns); - - @Override - public Vector viewPart(int offset, int length) { - if (offset < 0) { - throw new IndexException(offset, size); - } - if (offset + length > size) { - throw new IndexException(offset + length, size); - } - return new VectorView(this, offset, length); - } - - @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException") - @Override - public Vector clone() { - try { - AbstractVector r = (AbstractVector) super.clone(); - r.size = size; - r.lengthSquared = lengthSquared; - return r; - } catch (CloneNotSupportedException e) { - throw new IllegalStateException("Can't happen"); - } - } - - @Override - public Vector divide(double x) { - if (x == 1.0) { - return clone(); - } - Vector result = createOptimizedCopy(); - for (Element element : result.nonZeroes()) { - element.set(element.get() / x); - } - return result; - } - - @Override - public double dot(Vector x) { - if (size != x.size()) { - throw new CardinalityException(size, x.size()); - } - if (this == x) { - return getLengthSquared(); - } - return aggregate(x, Functions.PLUS, Functions.MULT); - } - - protected double dotSelf() { - return aggregate(Functions.PLUS, Functions.pow(2)); - } - - @Override - public double get(int index) { - if (index < 0 || index >= size) { - throw new IndexException(index, size); - } - return getQuick(index); - } - - @Override - public Element getElement(int index) { - return new LocalElement(index); - } - - @Override - public Vector normalize() { - return divide(Math.sqrt(getLengthSquared())); - } - - @Override - public Vector normalize(double power) { - return divide(norm(power)); - } - - @Override - public Vector logNormalize() { - return logNormalize(2.0, Math.sqrt(getLengthSquared())); - } - - @Override - public Vector logNormalize(double power) { - return logNormalize(power, norm(power)); - } - - public Vector logNormalize(double power, double normLength) { - // we can special case certain powers - if (Double.isInfinite(power) || power <= 1.0) { - throw new IllegalArgumentException("Power must be > 1 and < infinity"); - } else { - double denominator = normLength * Math.log(power); - Vector result = createOptimizedCopy(); - for (Element element : result.nonZeroes()) { - element.set(Math.log1p(element.get()) / denominator); - } - return result; - } - } - - @Override - public double norm(double power) { - if (power < 0.0) { - throw new IllegalArgumentException("Power must be >= 0"); - } - // We can special case certain powers. - if (Double.isInfinite(power)) { - return aggregate(Functions.MAX, Functions.ABS); - } else if (power == 2.0) { - return Math.sqrt(getLengthSquared()); - } else if (power == 1.0) { - double result = 0.0; - Iterator<Element> iterator = this.iterateNonZero(); - while (iterator.hasNext()) { - result += Math.abs(iterator.next().get()); - } - return result; - // TODO: this should ideally be used, but it's slower. - // return aggregate(Functions.PLUS, Functions.ABS); - } else if (power == 0.0) { - return getNumNonZeroElements(); - } else { - return Math.pow(aggregate(Functions.PLUS, Functions.pow(power)), 1.0 / power); - } - } - - @Override - public double getLengthSquared() { - if (lengthSquared >= 0.0) { - return lengthSquared; - } - return lengthSquared = dotSelf(); - } - - @Override - public void invalidateCachedLength() { - lengthSquared = -1; - } - - @Override - public double getDistanceSquared(Vector that) { - if (size != that.size()) { - throw new CardinalityException(size, that.size()); - } - double thisLength = getLengthSquared(); - double thatLength = that.getLengthSquared(); - double dot = dot(that); - double distanceEstimate = thisLength + thatLength - 2 * dot; - if (distanceEstimate > 1.0e-3 * (thisLength + thatLength)) { - // The vectors are far enough from each other that the formula is accurate. - return Math.max(distanceEstimate, 0); - } else { - return aggregate(that, Functions.PLUS, Functions.MINUS_SQUARED); - } - } - - @Override - public double maxValue() { - if (size == 0) { - return Double.NEGATIVE_INFINITY; - } - return aggregate(Functions.MAX, Functions.IDENTITY); - } - - @Override - public int maxValueIndex() { - int result = -1; - double max = Double.NEGATIVE_INFINITY; - int nonZeroElements = 0; - Iterator<Element> iter = this.iterateNonZero(); - while (iter.hasNext()) { - nonZeroElements++; - Element element = iter.next(); - double tmp = element.get(); - if (tmp > max) { - max = tmp; - result = element.index(); - } - } - // if the maxElement is negative and the vector is sparse then any - // unfilled element(0.0) could be the maxValue hence we need to - // find one of those elements - if (nonZeroElements < size && max < 0.0) { - for (Element element : all()) { - if (element.get() == 0.0) { - return element.index(); - } - } - } - return result; - } - - @Override - public double minValue() { - if (size == 0) { - return Double.POSITIVE_INFINITY; - } - return aggregate(Functions.MIN, Functions.IDENTITY); - } - - @Override - public int minValueIndex() { - int result = -1; - double min = Double.POSITIVE_INFINITY; - int nonZeroElements = 0; - Iterator<Element> iter = this.iterateNonZero(); - while (iter.hasNext()) { - nonZeroElements++; - Element element = iter.next(); - double tmp = element.get(); - if (tmp < min) { - min = tmp; - result = element.index(); - } - } - // if the maxElement is positive and the vector is sparse then any - // unfilled element(0.0) could be the maxValue hence we need to - // find one of those elements - if (nonZeroElements < size && min > 0.0) { - for (Element element : all()) { - if (element.get() == 0.0) { - return element.index(); - } - } - } - return result; - } - - @Override - public Vector plus(double x) { - Vector result = createOptimizedCopy(); - if (x == 0.0) { - return result; - } - return result.assign(Functions.plus(x)); - } - - @Override - public Vector plus(Vector that) { - if (size != that.size()) { - throw new CardinalityException(size, that.size()); - } - return createOptimizedCopy().assign(that, Functions.PLUS); - } - - @Override - public Vector minus(Vector that) { - if (size != that.size()) { - throw new CardinalityException(size, that.size()); - } - return createOptimizedCopy().assign(that, Functions.MINUS); - } - - @Override - public void set(int index, double value) { - if (index < 0 || index >= size) { - throw new IndexException(index, size); - } - setQuick(index, value); - } - - @Override - public void incrementQuick(int index, double increment) { - setQuick(index, getQuick(index) + increment); - } - - @Override - public Vector times(double x) { - if (x == 0.0) { - return like(); - } - return createOptimizedCopy().assign(Functions.mult(x)); - } - - /** - * Copy the current vector in the most optimum fashion. Used by immutable methods like plus(), minus(). - * Use this instead of vector.like().assign(vector). Sub-class can choose to override this method. - * - * @return a copy of the current vector. - */ - protected Vector createOptimizedCopy() { - return createOptimizedCopy(this); - } - - private static Vector createOptimizedCopy(Vector vector) { - Vector result; - if (vector.isDense()) { - result = vector.like().assign(vector, Functions.SECOND_LEFT_ZERO); - } else { - result = vector.clone(); - } - return result; - } - - @Override - public Vector times(Vector that) { - if (size != that.size()) { - throw new CardinalityException(size, that.size()); - } - - if (this.getNumNondefaultElements() <= that.getNumNondefaultElements()) { - return createOptimizedCopy(this).assign(that, Functions.MULT); - } else { - return createOptimizedCopy(that).assign(this, Functions.MULT); - } - } - - @Override - public double zSum() { - return aggregate(Functions.PLUS, Functions.IDENTITY); - } - - @Override - public int getNumNonZeroElements() { - int count = 0; - Iterator<Element> it = iterateNonZero(); - while (it.hasNext()) { - if (it.next().get() != 0.0) { - count++; - } - } - return count; - } - - @Override - public Vector assign(double value) { - Iterator<Element> it; - if (value == 0.0) { - // Make all the non-zero values 0. - it = iterateNonZero(); - while (it.hasNext()) { - it.next().set(value); - } - } else { - if (isSequentialAccess() && !isAddConstantTime()) { - // Update all the non-zero values and queue the updates for the zero vaues. - // The vector will become dense. - it = iterator(); - OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(); - while (it.hasNext()) { - Element element = it.next(); - if (element.get() == 0.0) { - updates.set(element.index(), value); - } else { - element.set(value); - } - } - mergeUpdates(updates); - } else { - for (int i = 0; i < size; ++i) { - setQuick(i, value); - } - } - } - invalidateCachedLength(); - return this; - } - - @Override - public Vector assign(double[] values) { - if (size != values.length) { - throw new CardinalityException(size, values.length); - } - if (isSequentialAccess() && !isAddConstantTime()) { - OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(); - Iterator<Element> it = iterator(); - while (it.hasNext()) { - Element element = it.next(); - int index = element.index(); - if (element.get() == 0.0) { - updates.set(index, values[index]); - } else { - element.set(values[index]); - } - } - mergeUpdates(updates); - } else { - for (int i = 0; i < size; ++i) { - setQuick(i, values[i]); - } - } - invalidateCachedLength(); - return this; - } - - @Override - public Vector assign(Vector other) { - return assign(other, Functions.SECOND); - } - - @Override - public Vector assign(DoubleDoubleFunction f, double y) { - Iterator<Element> iterator = f.apply(0, y) == 0 ? iterateNonZero() : iterator(); - while (iterator.hasNext()) { - Element element = iterator.next(); - element.set(f.apply(element.get(), y)); - } - invalidateCachedLength(); - return this; - } - - @Override - public Vector assign(DoubleFunction f) { - Iterator<Element> iterator = !f.isDensifying() ? iterateNonZero() : iterator(); - while (iterator.hasNext()) { - Element element = iterator.next(); - element.set(f.apply(element.get())); - } - invalidateCachedLength(); - return this; - } - - @Override - public Vector assign(Vector other, DoubleDoubleFunction function) { - if (size != other.size()) { - throw new CardinalityException(size, other.size()); - } - VectorBinaryAssign.assignBest(this, other, function); - invalidateCachedLength(); - return this; - } - - @Override - public Matrix cross(Vector other) { - Matrix result = matrixLike(size, other.size()); - Iterator<Vector.Element> it = iterateNonZero(); - while (it.hasNext()) { - Vector.Element e = it.next(); - int row = e.index(); - result.assignRow(row, other.times(getQuick(row))); - } - return result; - } - - @Override - public final int size() { - return size; - } - - @Override - public String asFormatString() { - return toString(); - } - - @Override - public int hashCode() { - int result = size; - Iterator<Element> iter = iterateNonZero(); - while (iter.hasNext()) { - Element ele = iter.next(); - result += ele.index() * RandomUtils.hashDouble(ele.get()); - } - return result; - } - - /** - * Determines whether this {@link Vector} represents the same logical vector as another - * object. Two {@link Vector}s are equal (regardless of implementation) if the value at - * each index is the same, and the cardinalities are the same. - */ - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Vector)) { - return false; - } - Vector that = (Vector) o; - return size == that.size() && aggregate(that, Functions.PLUS, Functions.MINUS_ABS) == 0.0; - } - - @Override - public String toString() { - return toString(null); - } - - public String toString(String[] dictionary) { - StringBuilder result = new StringBuilder(); - result.append('{'); - for (int index = 0; index < size; index++) { - double value = getQuick(index); - if (value != 0.0) { - result.append(dictionary != null && dictionary.length > index ? dictionary[index] : index); - result.append(':'); - result.append(value); - result.append(','); - } - } - if (result.length() > 1) { - result.setCharAt(result.length() - 1, '}'); - } else { - result.append('}'); - } - return result.toString(); - } - - /** - * toString() implementation for sparse vectors via {@link #nonZeroes()} method - * @return String representation of the vector - */ - public String sparseVectorToString() { - Iterator<Element> it = iterateNonZero(); - if (!it.hasNext()) { - return "{}"; - } - else { - StringBuilder result = new StringBuilder(); - result.append('{'); - while (it.hasNext()) { - Vector.Element e = it.next(); - result.append(e.index()); - result.append(':'); - result.append(e.get()); - result.append(','); - } - result.setCharAt(result.length() - 1, '}'); - return result.toString(); - } - } - - protected final class LocalElement implements Element { - int index; - - LocalElement(int index) { - this.index = index; - } - - @Override - public double get() { - return getQuick(index); - } - - @Override - public int index() { - return index; - } - - @Override - public void set(double value) { - setQuick(index, value); - } - } -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/Algebra.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/Algebra.java b/core/src/main/java/org/apache/mahout/math/Algebra.java deleted file mode 100644 index 3049057..0000000 --- a/core/src/main/java/org/apache/mahout/math/Algebra.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * 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.mahout.math; - -public final class Algebra { - - private Algebra() { - } - - public static Vector mult(Matrix m, Vector v) { - if (m.numRows() != v.size()) { - throw new CardinalityException(m.numRows(), v.size()); - } - // Use a Dense Vector for the moment, - Vector result = new DenseVector(m.numRows()); - - for (int i = 0; i < m.numRows(); i++) { - result.set(i, m.viewRow(i).dot(v)); - } - - return result; - } - - /** Returns sqrt(a^2 + b^2) without under/overflow. */ - public static double hypot(double a, double b) { - double r; - if (Math.abs(a) > Math.abs(b)) { - r = b / a; - r = Math.abs(a) * Math.sqrt(1 + r * r); - } else if (b != 0) { - r = a / b; - r = Math.abs(b) * Math.sqrt(1 + r * r); - } else { - r = 0.0; - } - return r; - } - - /** - * Compute Maximum Absolute Row Sum Norm of input Matrix m - * http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html - */ - public static double getNorm(Matrix m) { - double max = 0.0; - for (int i = 0; i < m.numRows(); i++) { - int sum = 0; - Vector cv = m.viewRow(i); - for (int j = 0; j < cv.size(); j++) { - sum += (int) Math.abs(cv.getQuick(j)); - } - if (sum > max) { - max = sum; - } - } - return max; - } - -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/Arrays.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/Arrays.java b/core/src/main/java/org/apache/mahout/math/Arrays.java deleted file mode 100644 index 802ffb7..0000000 --- a/core/src/main/java/org/apache/mahout/math/Arrays.java +++ /dev/null @@ -1,662 +0,0 @@ -/* -Copyright 1999 CERN - European Organization for Nuclear Research. -Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose -is hereby granted without fee, provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear in supporting documentation. -CERN makes no representations about the suitability of this software for any purpose. -It is provided "as is" without expressed or implied warranty. -*/ -package org.apache.mahout.math; - -/** - * Array manipulations; complements <tt>java.util.Arrays</tt>. - * - * @see java.util.Arrays - * @see org.apache.mahout.math.Sorting - * - */ -public final class Arrays { - - private Arrays() { - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static byte[] ensureCapacity(byte[] array, int minCapacity) { - int oldCapacity = array.length; - byte[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new byte[newCapacity]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static char[] ensureCapacity(char[] array, int minCapacity) { - int oldCapacity = array.length; - char[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new char[newCapacity]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static double[] ensureCapacity(double[] array, int minCapacity) { - int oldCapacity = array.length; - double[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new double[newCapacity]; - //for (int i = oldCapacity; --i >= 0; ) newArray[i] = array[i]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static float[] ensureCapacity(float[] array, int minCapacity) { - int oldCapacity = array.length; - float[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new float[newCapacity]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static int[] ensureCapacity(int[] array, int minCapacity) { - int oldCapacity = array.length; - int[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new int[newCapacity]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static long[] ensureCapacity(long[] array, int minCapacity) { - int oldCapacity = array.length; - long[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new long[newCapacity]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static Object[] ensureCapacity(Object[] array, int minCapacity) { - int oldCapacity = array.length; - Object[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new Object[newCapacity]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static short[] ensureCapacity(short[] array, int minCapacity) { - int oldCapacity = array.length; - short[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new short[newCapacity]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Ensures that a given array can hold up to <tt>minCapacity</tt> elements. - * - * Returns the identical array if it can hold at least the number of elements specified. Otherwise, returns a new - * array with increased capacity containing the same elements, ensuring that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity. - */ - public static boolean[] ensureCapacity(boolean[] array, int minCapacity) { - int oldCapacity = array.length; - boolean[] newArray; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3) / 2 + 1; - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - - newArray = new boolean[newCapacity]; - System.arraycopy(array, 0, newArray, 0, oldCapacity); - } else { - newArray = array; - } - return newArray; - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(byte[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(char[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(double[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(float[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(int[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(long[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(Object[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(short[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Returns a string representation of the specified array. The string representation consists of a list of the - * arrays's elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are separated by the characters - * <tt>", "</tt> (comma and space). - * - * @return a string representation of the specified array. - */ - public static String toString(boolean[] array) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - int maxIndex = array.length - 1; - for (int i = 0; i <= maxIndex; i++) { - buf.append(array[i]); - if (i < maxIndex) { - buf.append(", "); - } - } - buf.append(']'); - return buf.toString(); - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static byte[] trimToCapacity(byte[] array, int maxCapacity) { - if (array.length > maxCapacity) { - byte[] oldArray = array; - array = new byte[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static char[] trimToCapacity(char[] array, int maxCapacity) { - if (array.length > maxCapacity) { - char[] oldArray = array; - array = new char[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static double[] trimToCapacity(double[] array, int maxCapacity) { - if (array.length > maxCapacity) { - double[] oldArray = array; - array = new double[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static float[] trimToCapacity(float[] array, int maxCapacity) { - if (array.length > maxCapacity) { - float[] oldArray = array; - array = new float[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static int[] trimToCapacity(int[] array, int maxCapacity) { - if (array.length > maxCapacity) { - int[] oldArray = array; - array = new int[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static long[] trimToCapacity(long[] array, int maxCapacity) { - if (array.length > maxCapacity) { - long[] oldArray = array; - array = new long[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static Object[] trimToCapacity(Object[] array, int maxCapacity) { - if (array.length > maxCapacity) { - Object[] oldArray = array; - array = new Object[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static short[] trimToCapacity(short[] array, int maxCapacity) { - if (array.length > maxCapacity) { - short[] oldArray = array; - array = new short[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * Ensures that the specified array cannot hold more than <tt>maxCapacity</tt> elements. An application can use this - * operation to minimize array storage. <p> Returns the identical array if <tt>array.length <= maxCapacity</tt>. - * Otherwise, returns a new array with a length of <tt>maxCapacity</tt> containing the first <tt>maxCapacity</tt> - * elements of <tt>array</tt>. - * - * @param maxCapacity the desired maximum capacity. - */ - public static boolean[] trimToCapacity(boolean[] array, int maxCapacity) { - if (array.length > maxCapacity) { - boolean[] oldArray = array; - array = new boolean[maxCapacity]; - System.arraycopy(oldArray, 0, array, 0, maxCapacity); - } - return array; - } - - /** - * {@link java.util.Arrays#copyOf} compatibility with Java 1.5. - */ - public static byte[] copyOf(byte[] src, int length) { - byte[] result = new byte [length]; - System.arraycopy(src, 0, result, 0, Math.min(length, src.length)); - return result; - } - - /** - * {@link java.util.Arrays#copyOf} compatibility with Java 1.5. - */ - public static char[] copyOf(char[] src, int length) { - char[] result = new char [length]; - System.arraycopy(src, 0, result, 0, Math.min(length, src.length)); - return result; - } - - /** - * {@link java.util.Arrays#copyOf} compatibility with Java 1.5. - */ - public static short[] copyOf(short[] src, int length) { - short[] result = new short [length]; - System.arraycopy(src, 0, result, 0, Math.min(length, src.length)); - return result; - } - - /** - * {@link java.util.Arrays#copyOf} compatibility with Java 1.5. - */ - public static int[] copyOf(int[] src, int length) { - int[] result = new int [length]; - System.arraycopy(src, 0, result, 0, Math.min(length, src.length)); - return result; - } - - /** - * {@link java.util.Arrays#copyOf} compatibility with Java 1.5. - */ - public static float[] copyOf(float[] src, int length) { - float[] result = new float [length]; - System.arraycopy(src, 0, result, 0, Math.min(length, src.length)); - return result; - } - - /** - * {@link java.util.Arrays#copyOf} compatibility with Java 1.5. - */ - public static double[] copyOf(double[] src, int length) { - double[] result = new double [length]; - System.arraycopy(src, 0, result, 0, Math.min(length, src.length)); - return result; - } - - /** - * {@link java.util.Arrays#copyOf} compatibility with Java 1.5. - */ - public static long[] copyOf(long[] src, int length) { - long[] result = new long [length]; - System.arraycopy(src, 0, result, 0, Math.min(length, src.length)); - return result; - } -}
