http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/VectorBinaryAssign.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/VectorBinaryAssign.java b/core/src/main/java/org/apache/mahout/math/VectorBinaryAssign.java deleted file mode 100644 index 2cfd120..0000000 --- a/core/src/main/java/org/apache/mahout/math/VectorBinaryAssign.java +++ /dev/null @@ -1,667 +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 org.apache.mahout.math.Vector.Element; -import org.apache.mahout.math.function.DoubleDoubleFunction; -//import org.apache.mahout.math.set.OpenIntHashSet; - -import java.util.Iterator; - -/** - * Abstract class encapsulating different algorithms that perform the Vector operations assign(). - * x.assign(y, f), for x and y Vectors and f a DoubleDouble function: - * - applies the function f to every element in x and y, f(xi, yi) - * - assigns xi = f(xi, yi) for all indices i - * - * The names of variables, methods and classes used here follow the following conventions: - * The vector being assigned to (the left hand side) is called this or x. - * The right hand side is called that or y. - * The function to be applied is called f. - * - * The different algorithms take into account the different characteristics of vector classes: - * - whether the vectors support sequential iteration (isSequential()) - * - whether the vectors support constant-time additions (isAddConstantTime()) - * - what the lookup cost is (getLookupCost()) - * - what the iterator advancement cost is (getIteratorAdvanceCost()) - * - * The names of the actual classes (they're nested in VectorBinaryAssign) describe the used for assignment. - * The most important optimization is iterating just through the nonzeros (only possible if f(0, 0) = 0). - * There are 4 main possibilities: - * - iterating through the nonzeros of just one vector and looking up the corresponding elements in the other - * - iterating through the intersection of nonzeros (those indices where both vectors have nonzero values) - * - iterating through the union of nonzeros (those indices where at least one of the vectors has a nonzero value) - * - iterating through all the elements in some way (either through both at the same time, both one after the other, - * looking up both, looking up just one). - * Then, there are two additional sub-possibilities: - * - if a new value can be added to x in constant time (isAddConstantTime()), the *Inplace updates are used - * - otherwise (really just for SequentialAccessSparseVectors right now), the *Merge updates are used, where - * a sorted list of (index, value) pairs is merged into the vector at the end. - * - * The internal details are not important and a particular algorithm should generally not be called explicitly. - * The best one will be selected through assignBest(), which is itself called through Vector.assign(). - * - * See https://docs.google.com/document/d/1g1PjUuvjyh2LBdq2_rKLIcUiDbeOORA1sCJiSsz-JVU/edit# for a more detailed - * explanation. - */ -public abstract class VectorBinaryAssign { - public static final VectorBinaryAssign[] OPERATIONS = { - new AssignNonzerosIterateThisLookupThat(), - new AssignNonzerosIterateThatLookupThisMergeUpdates(), - new AssignNonzerosIterateThatLookupThisInplaceUpdates(), - - new AssignIterateIntersection(), - - new AssignIterateUnionSequentialMergeUpdates(), - new AssignIterateUnionSequentialInplaceUpdates(), -// new AssignIterateUnionRandomMergeUpdates(), -// new AssignIterateUnionRandomInplaceUpdates(), - - new AssignAllIterateSequentialMergeUpdates(), - new AssignAllIterateSequentialInplaceUpdates(), - new AssignAllIterateThisLookupThatMergeUpdates(), - new AssignAllIterateThisLookupThatInplaceUpdates(), - new AssignAllIterateThatLookupThisMergeUpdates(), - new AssignAllIterateThatLookupThisInplaceUpdates(), - new AssignAllLoopMergeUpdates(), - new AssignAllLoopInplaceUpdates(), - }; - - /** - * Returns true iff we can use this algorithm to apply f to x and y component-wise and assign the result to x. - */ - public abstract boolean isValid(Vector x, Vector y, DoubleDoubleFunction f); - - /** - * Estimates the cost of using this algorithm to compute the assignment. The algorithm is assumed to be valid. - */ - public abstract double estimateCost(Vector x, Vector y, DoubleDoubleFunction f); - - /** - * Main method that applies f to x and y component-wise assigning the results to x. It returns the modified vector, - * x. - */ - public abstract Vector assign(Vector x, Vector y, DoubleDoubleFunction f); - - /** - * The best operation is the least expensive valid one. - */ - public static VectorBinaryAssign getBestOperation(Vector x, Vector y, DoubleDoubleFunction f) { - int bestOperationIndex = -1; - double bestCost = Double.POSITIVE_INFINITY; - for (int i = 0; i < OPERATIONS.length; ++i) { - if (OPERATIONS[i].isValid(x, y, f)) { - double cost = OPERATIONS[i].estimateCost(x, y, f); - if (cost < bestCost) { - bestCost = cost; - bestOperationIndex = i; - } - } - } - return OPERATIONS[bestOperationIndex]; - } - - /** - * This is the method that should be used when assigning. It selects the best algorithm and applies it. - * Note that it does NOT invalidate the cached length of the Vector and should only be used through the wrapprs - * in AbstractVector. - */ - public static Vector assignBest(Vector x, Vector y, DoubleDoubleFunction f) { - return getBestOperation(x, y, f).assign(x, y, f); - } - - /** - * If f(0, y) = 0, the zeros in x don't matter and we can simply iterate through the nonzeros of x. - * To get the corresponding element of y, we perform a lookup. - * There are no *Merge or *Inplace versions because in this case x cannot become more dense because of f, meaning - * all changes will occur at indices whose values are already nonzero. - */ - public static class AssignNonzerosIterateThisLookupThat extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return f.isLikeLeftMult(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return x.getNumNondefaultElements() * x.getIteratorAdvanceCost() * y.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - for (Element xe : x.nonZeroes()) { - xe.set(f.apply(xe.get(), y.getQuick(xe.index()))); - } - return x; - } - } - - /** - * If f(x, 0) = x, the zeros in y don't matter and we can simply iterate through the nonzeros of y. - * We get the corresponding element of x through a lookup and update x inplace. - */ - public static class AssignNonzerosIterateThatLookupThisInplaceUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return f.isLikeRightPlus(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return y.getNumNondefaultElements() * y.getIteratorAdvanceCost() * x.getLookupCost() * x.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - for (Element ye : y.nonZeroes()) { - x.setQuick(ye.index(), f.apply(x.getQuick(ye.index()), ye.get())); - } - return x; - } - } - - /** - * If f(x, 0) = x, the zeros in y don't matter and we can simply iterate through the nonzeros of y. - * We get the corresponding element of x through a lookup and update x by merging. - */ - public static class AssignNonzerosIterateThatLookupThisMergeUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return f.isLikeRightPlus() && y.isSequentialAccess() && !x.isAddConstantTime(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return y.getNumNondefaultElements() * y.getIteratorAdvanceCost() * y.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(false); - for (Element ye : y.nonZeroes()) { - updates.set(ye.index(), f.apply(x.getQuick(ye.index()), ye.get())); - } - x.mergeUpdates(updates); - return x; - } - } - - /** - * If f(x, 0) = x and f(0, y) = 0 the zeros in x and y don't matter and we can iterate through the nonzeros - * in both x and y. - * This is only possible if both x and y support sequential access. - */ - public static class AssignIterateIntersection extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return f.isLikeLeftMult() && f.isLikeRightPlus() && x.isSequentialAccess() && y.isSequentialAccess(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return Math.min(x.getNumNondefaultElements() * x.getIteratorAdvanceCost(), - y.getNumNondefaultElements() * y.getIteratorAdvanceCost()); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - Iterator<Element> xi = x.nonZeroes().iterator(); - Iterator<Element> yi = y.nonZeroes().iterator(); - Element xe = null; - Element ye = null; - boolean advanceThis = true; - boolean advanceThat = true; - while (true) { - if (advanceThis) { - if (xi.hasNext()) { - xe = xi.next(); - } else { - break; - } - } - if (advanceThat) { - if (yi.hasNext()) { - ye = yi.next(); - } else { - break; - } - } - if (xe.index() == ye.index()) { - xe.set(f.apply(xe.get(), ye.get())); - advanceThis = true; - advanceThat = true; - } else { - if (xe.index() < ye.index()) { // f(x, 0) = 0 - advanceThis = true; - advanceThat = false; - } else { // f(0, y) = 0 - advanceThis = false; - advanceThat = true; - } - } - } - return x; - } - } - - /** - * If f(0, 0) = 0 we can iterate through the nonzeros in either x or y. - * In this case we iterate through them in parallel and update x by merging. Because we're iterating through - * both vectors at the same time, x and y need to support sequential access. - */ - public static class AssignIterateUnionSequentialMergeUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return !f.isDensifying() && x.isSequentialAccess() && y.isSequentialAccess() && !x.isAddConstantTime(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return Math.max(x.getNumNondefaultElements() * x.getIteratorAdvanceCost(), - y.getNumNondefaultElements() * y.getIteratorAdvanceCost()); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - Iterator<Element> xi = x.nonZeroes().iterator(); - Iterator<Element> yi = y.nonZeroes().iterator(); - Element xe = null; - Element ye = null; - boolean advanceThis = true; - boolean advanceThat = true; - OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(false); - while (true) { - if (advanceThis) { - if (xi.hasNext()) { - xe = xi.next(); - } else { - xe = null; - } - } - if (advanceThat) { - if (yi.hasNext()) { - ye = yi.next(); - } else { - ye = null; - } - } - if (xe != null && ye != null) { // both vectors have nonzero elements - if (xe.index() == ye.index()) { - xe.set(f.apply(xe.get(), ye.get())); - advanceThis = true; - advanceThat = true; - } else { - if (xe.index() < ye.index()) { // f(x, 0) - xe.set(f.apply(xe.get(), 0)); - advanceThis = true; - advanceThat = false; - } else { - updates.set(ye.index(), f.apply(0, ye.get())); - advanceThis = false; - advanceThat = true; - } - } - } else if (xe != null) { // just the first one still has nonzeros - xe.set(f.apply(xe.get(), 0)); - advanceThis = true; - advanceThat = false; - } else if (ye != null) { // just the second one has nonzeros - updates.set(ye.index(), f.apply(0, ye.get())); - advanceThis = false; - advanceThat = true; - } else { // we're done, both are empty - break; - } - } - x.mergeUpdates(updates); - return x; - } - } - - /** - * If f(0, 0) = 0 we can iterate through the nonzeros in either x or y. - * In this case we iterate through them in parallel and update x inplace. Because we're iterating through - * both vectors at the same time, x and y need to support sequential access. - */ - public static class AssignIterateUnionSequentialInplaceUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return !f.isDensifying() && x.isSequentialAccess() && y.isSequentialAccess() && x.isAddConstantTime(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return Math.max(x.getNumNondefaultElements() * x.getIteratorAdvanceCost(), - y.getNumNondefaultElements() * y.getIteratorAdvanceCost()); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - Iterator<Element> xi = x.nonZeroes().iterator(); - Iterator<Element> yi = y.nonZeroes().iterator(); - Element xe = null; - Element ye = null; - boolean advanceThis = true; - boolean advanceThat = true; - while (true) { - if (advanceThis) { - if (xi.hasNext()) { - xe = xi.next(); - } else { - xe = null; - } - } - if (advanceThat) { - if (yi.hasNext()) { - ye = yi.next(); - } else { - ye = null; - } - } - if (xe != null && ye != null) { // both vectors have nonzero elements - if (xe.index() == ye.index()) { - xe.set(f.apply(xe.get(), ye.get())); - advanceThis = true; - advanceThat = true; - } else { - if (xe.index() < ye.index()) { // f(x, 0) - xe.set(f.apply(xe.get(), 0)); - advanceThis = true; - advanceThat = false; - } else { - x.setQuick(ye.index(), f.apply(0, ye.get())); - advanceThis = false; - advanceThat = true; - } - } - } else if (xe != null) { // just the first one still has nonzeros - xe.set(f.apply(xe.get(), 0)); - advanceThis = true; - advanceThat = false; - } else if (ye != null) { // just the second one has nonzeros - x.setQuick(ye.index(), f.apply(0, ye.get())); - advanceThis = false; - advanceThat = true; - } else { // we're done, both are empty - break; - } - } - return x; - } - } - - /** - * If f(0, 0) = 0 we can iterate through the nonzeros in either x or y. - * In this case, we iterate through the nozeros of x and y alternatively (this works even when one of them - * doesn't support sequential access). Since we're merging the results into x, when iterating through y, the - * order of iteration matters and y must support sequential access. - */ -// public static class AssignIterateUnionRandomMergeUpdates extends VectorBinaryAssign { -// -// @Override -// public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { -// return !f.isDensifying() && !x.isAddConstantTime() && y.isSequentialAccess(); -// } -// -// @Override -// public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { -// return Math.max(x.getNumNondefaultElements() * x.getIteratorAdvanceCost() * y.getLookupCost(), -// y.getNumNondefaultElements() * y.getIteratorAdvanceCost() * x.getLookupCost()); -// } - -// @Override -// public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { -// OpenIntHashSet visited = new OpenIntHashSet(); -// for (Element xe : x.nonZeroes()) { -// xe.set(f.apply(xe.get(), y.getQuick(xe.index()))); -// visited.add(xe.index()); -// } -// OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(false); -// for (Element ye : y.nonZeroes()) { -// if (!visited.contains(ye.index())) { -// updates.set(ye.index(), f.apply(x.getQuick(ye.index()), ye.get())); -// } -// } -// x.mergeUpdates(updates); -// return x; -// } -// } - - /** - * If f(0, 0) = 0 we can iterate through the nonzeros in either x or y. - * In this case, we iterate through the nozeros of x and y alternatively (this works even when one of them - * doesn't support sequential access). Because updates to x are inplace, neither x, nor y need to support - * sequential access. - */ -// public static class AssignIterateUnionRandomInplaceUpdates extends VectorBinaryAssign { -// -// @Override -// public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { -// return !f.isDensifying() && x.isAddConstantTime(); -// } -// -// @Override -// public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { -// return Math.max(x.getNumNondefaultElements() * x.getIteratorAdvanceCost() * y.getLookupCost(), -// y.getNumNondefaultElements() * y.getIteratorAdvanceCost() * x.getLookupCost()); -// } -//// @Override -//// public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { -//// OpenIntHashSet visited = new OpenIntHashSet(); -//// for (Element xe : x.nonZeroes()) { -//// xe.set(f.apply(xe.get(), y.getQuick(xe.index()))); -//// visited.add(xe.index()); -//// } -//// for (Element ye : y.nonZeroes()) { -//// if (!visited.contains(ye.index())) { -//// x.setQuick(ye.index(), f.apply(x.getQuick(ye.index()), ye.get())); -//// } -//// } -//// return x; -//// } -// } - - public static class AssignAllIterateSequentialMergeUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return x.isSequentialAccess() && y.isSequentialAccess() && !x.isAddConstantTime() && !x.isDense() && !y.isDense(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return Math.max(x.size() * x.getIteratorAdvanceCost(), y.size() * y.getIteratorAdvanceCost()); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - Iterator<Element> xi = x.all().iterator(); - Iterator<Element> yi = y.all().iterator(); - OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(false); - while (xi.hasNext() && yi.hasNext()) { - Element xe = xi.next(); - updates.set(xe.index(), f.apply(xe.get(), yi.next().get())); - } - x.mergeUpdates(updates); - return x; - } - } - - public static class AssignAllIterateSequentialInplaceUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return x.isSequentialAccess() && y.isSequentialAccess() && x.isAddConstantTime() - && !x.isDense() && !y.isDense(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return Math.max(x.size() * x.getIteratorAdvanceCost(), y.size() * y.getIteratorAdvanceCost()); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - Iterator<Element> xi = x.all().iterator(); - Iterator<Element> yi = y.all().iterator(); - while (xi.hasNext() && yi.hasNext()) { - Element xe = xi.next(); - x.setQuick(xe.index(), f.apply(xe.get(), yi.next().get())); - } - return x; - } - } - - public static class AssignAllIterateThisLookupThatMergeUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return !x.isAddConstantTime() && !x.isDense(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return x.size() * x.getIteratorAdvanceCost() * y.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(false); - for (Element xe : x.all()) { - updates.set(xe.index(), f.apply(xe.get(), y.getQuick(xe.index()))); - } - x.mergeUpdates(updates); - return x; - } - } - - public static class AssignAllIterateThisLookupThatInplaceUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return x.isAddConstantTime() && !x.isDense(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return x.size() * x.getIteratorAdvanceCost() * y.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - for (Element xe : x.all()) { - x.setQuick(xe.index(), f.apply(xe.get(), y.getQuick(xe.index()))); - } - return x; - } - } - - public static class AssignAllIterateThatLookupThisMergeUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return !x.isAddConstantTime() && !y.isDense(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return y.size() * y.getIteratorAdvanceCost() * x.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(false); - for (Element ye : y.all()) { - updates.set(ye.index(), f.apply(x.getQuick(ye.index()), ye.get())); - } - x.mergeUpdates(updates); - return x; - } - } - - public static class AssignAllIterateThatLookupThisInplaceUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return x.isAddConstantTime() && !y.isDense(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return y.size() * y.getIteratorAdvanceCost() * x.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - for (Element ye : y.all()) { - x.setQuick(ye.index(), f.apply(x.getQuick(ye.index()), ye.get())); - } - return x; - } - } - - public static class AssignAllLoopMergeUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return !x.isAddConstantTime(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return x.size() * x.getLookupCost() * y.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - OrderedIntDoubleMapping updates = new OrderedIntDoubleMapping(false); - for (int i = 0; i < x.size(); ++i) { - updates.set(i, f.apply(x.getQuick(i), y.getQuick(i))); - } - x.mergeUpdates(updates); - return x; - } - } - - public static class AssignAllLoopInplaceUpdates extends VectorBinaryAssign { - - @Override - public boolean isValid(Vector x, Vector y, DoubleDoubleFunction f) { - return x.isAddConstantTime(); - } - - @Override - public double estimateCost(Vector x, Vector y, DoubleDoubleFunction f) { - return x.size() * x.getLookupCost() * y.getLookupCost(); - } - - @Override - public Vector assign(Vector x, Vector y, DoubleDoubleFunction f) { - for (int i = 0; i < x.size(); ++i) { - x.setQuick(i, f.apply(x.getQuick(i), y.getQuick(i))); - } - return x; - } - } -}
http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/VectorIterable.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/VectorIterable.java b/core/src/main/java/org/apache/mahout/math/VectorIterable.java deleted file mode 100644 index 8414fdb..0000000 --- a/core/src/main/java/org/apache/mahout/math/VectorIterable.java +++ /dev/null @@ -1,56 +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; - -public interface VectorIterable extends Iterable<MatrixSlice> { - - /* Iterate all rows in order */ - Iterator<MatrixSlice> iterateAll(); - - /* Iterate all non empty rows in arbitrary order */ - Iterator<MatrixSlice> iterateNonEmpty(); - - int numSlices(); - - int numRows(); - - int numCols(); - - /** - * Return a new vector with cardinality equal to getNumRows() of this matrix which is the matrix product of the - * recipient and the argument - * - * @param v a vector with cardinality equal to getNumCols() of the recipient - * @return a new vector (typically a DenseVector) - * @throws CardinalityException if this.getNumRows() != v.size() - */ - Vector times(Vector v); - - /** - * Convenience method for producing this.transpose().times(this.times(v)), which can be implemented with only one pass - * over the matrix, without making the transpose() call (which can be expensive if the matrix is sparse) - * - * @param v a vector with cardinality equal to getNumCols() of the recipient - * @return a new vector (typically a DenseVector) with cardinality equal to that of the argument. - * @throws CardinalityException if this.getNumCols() != v.size() - */ - Vector timesSquared(Vector v); - -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/VectorView.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/VectorView.java b/core/src/main/java/org/apache/mahout/math/VectorView.java deleted file mode 100644 index 62c5490..0000000 --- a/core/src/main/java/org/apache/mahout/math/VectorView.java +++ /dev/null @@ -1,238 +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.collect.AbstractIterator; - -/** Implements subset view of a Vector */ -public class VectorView extends AbstractVector { - - protected Vector vector; - - // the offset into the Vector - protected int offset; - - /** For serialization purposes only */ - public VectorView() { - super(0); - } - - public VectorView(Vector vector, int offset, int cardinality) { - super(cardinality); - this.vector = vector; - this.offset = offset; - } - - @Override - protected Matrix matrixLike(int rows, int columns) { - return ((AbstractVector) vector).matrixLike(rows, columns); - } - - @Override - public Vector clone() { - VectorView r = (VectorView) super.clone(); - r.vector = vector.clone(); - r.offset = offset; - return r; - } - - @Override - public boolean isDense() { - return vector.isDense(); - } - - @Override - public boolean isSequentialAccess() { - return vector.isSequentialAccess(); - } - - @Override - public VectorView like() { - return new VectorView(vector.like(), offset, size()); - } - - @Override - public Vector like(int cardinality) { - return vector.like(cardinality); - } - - @Override - public double getQuick(int index) { - return vector.getQuick(offset + index); - } - - @Override - public void setQuick(int index, double value) { - vector.setQuick(offset + index, value); - } - - @Override - public int getNumNondefaultElements() { - return size(); - } - - @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(vector, offset + this.offset, length); - } - - /** @return true if index is a valid index in the underlying Vector */ - private boolean isInView(int index) { - return index >= offset && index < offset + size(); - } - - @Override - public Iterator<Element> iterateNonZero() { - return new NonZeroIterator(); - } - - @Override - public Iterator<Element> iterator() { - return new AllIterator(); - } - - public final class NonZeroIterator extends AbstractIterator<Element> { - - private final Iterator<Element> it; - - private NonZeroIterator() { - it = vector.nonZeroes().iterator(); - } - - @Override - protected Element computeNext() { - while (it.hasNext()) { - Element el = it.next(); - if (isInView(el.index()) && el.get() != 0) { - Element decorated = el; /* vector.getElement(el.index()); */ - return new DecoratorElement(decorated); - } - } - return endOfData(); - } - - } - - public final class AllIterator extends AbstractIterator<Element> { - - private final Iterator<Element> it; - - private AllIterator() { - it = vector.all().iterator(); - } - - @Override - protected Element computeNext() { - while (it.hasNext()) { - Element el = it.next(); - if (isInView(el.index())) { - Element decorated = vector.getElement(el.index()); - return new DecoratorElement(decorated); - } - } - return endOfData(); // No element was found - } - - } - - private final class DecoratorElement implements Element { - - private final Element decorated; - - private DecoratorElement(Element decorated) { - this.decorated = decorated; - } - - @Override - public double get() { - return decorated.get(); - } - - @Override - public int index() { - return decorated.index() - offset; - } - - @Override - public void set(double value) { - decorated.set(value); - } - } - - @Override - public double getLengthSquared() { - double result = 0.0; - int size = size(); - for (int i = 0; i < size; i++) { - double value = getQuick(i); - result += value * value; - } - return result; - } - - @Override - public double getDistanceSquared(Vector v) { - double result = 0.0; - int size = size(); - for (int i = 0; i < size; i++) { - double delta = getQuick(i) - v.getQuick(i); - result += delta * delta; - } - return result; - } - - @Override - public double getLookupCost() { - return vector.getLookupCost(); - } - - @Override - public double getIteratorAdvanceCost() { - // TODO: remove the 2x after fixing the Element iterator - return 2 * vector.getIteratorAdvanceCost(); - } - - @Override - public boolean isAddConstantTime() { - return vector.isAddConstantTime(); - } - - /** - * 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) { - for (int i = 0; i < updates.getNumMappings(); ++i) { - updates.setIndexAt(i, updates.indexAt(i) + offset); - } - vector.mergeUpdates(updates); - } -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/WeightedVector.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/WeightedVector.java b/core/src/main/java/org/apache/mahout/math/WeightedVector.java deleted file mode 100644 index c8fdfac..0000000 --- a/core/src/main/java/org/apache/mahout/math/WeightedVector.java +++ /dev/null @@ -1,87 +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; - -/** - * Decorates a vector with a floating point weight and an index. - */ -public class WeightedVector extends DelegatingVector { - private static final int INVALID_INDEX = -1; - private double weight; - private int index; - - protected WeightedVector(double weight, int index) { - super(); - this.weight = weight; - this.index = index; - } - - public WeightedVector(Vector v, double weight, int index) { - super(v); - this.weight = weight; - this.index = index; - } - - public WeightedVector(Vector v, Vector projection, int index) { - super(v); - this.index = index; - this.weight = v.dot(projection); - } - - public static WeightedVector project(Vector v, Vector projection) { - return project(v, projection, INVALID_INDEX); - } - - public static WeightedVector project(Vector v, Vector projection, int index) { - return new WeightedVector(v, projection, index); - } - - public double getWeight() { - return weight; - } - - public int getIndex() { - return index; - } - - public void setWeight(double newWeight) { - this.weight = newWeight; - } - - public void setIndex(int index) { - this.index = index; - } - - @Override - public Vector like() { - return new WeightedVector(getVector().like(), weight, index); - } - - @Override - public String toString() { - return String.format("index=%d, weight=%.2f, v=%s", index, weight, getVector()); - } - - @Override - public WeightedVector clone() { - WeightedVector v = (WeightedVector)super.clone(); - v.weight = weight; - v.index = index; - return v; - } -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/WeightedVectorComparator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/WeightedVectorComparator.java b/core/src/main/java/org/apache/mahout/math/WeightedVectorComparator.java deleted file mode 100644 index 9fdd621..0000000 --- a/core/src/main/java/org/apache/mahout/math/WeightedVectorComparator.java +++ /dev/null @@ -1,54 +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.io.Serializable; -import java.util.Comparator; - -/** - * Orders {@link WeightedVector} by {@link WeightedVector#getWeight()}. - */ -public final class WeightedVectorComparator implements Comparator<WeightedVector>, Serializable { - - private static final double DOUBLE_EQUALITY_ERROR = 1.0e-8; - - @Override - public int compare(WeightedVector a, WeightedVector b) { - if (a == b) { - return 0; - } - double aWeight = a.getWeight(); - double bWeight = b.getWeight(); - int r = Double.compare(aWeight, bWeight); - if (r != 0 && Math.abs(aWeight - bWeight) >= DOUBLE_EQUALITY_ERROR) { - return r; - } - double diff = a.minus(b).norm(1); - if (diff < 1.0e-12) { - return 0; - } - for (Vector.Element element : a.all()) { - r = Double.compare(element.get(), b.get(element.index())); - if (r != 0) { - return r; - } - } - return 0; - } - -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/flavor/BackEnum.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/flavor/BackEnum.java b/core/src/main/java/org/apache/mahout/math/flavor/BackEnum.java deleted file mode 100644 index 1782f04..0000000 --- a/core/src/main/java/org/apache/mahout/math/flavor/BackEnum.java +++ /dev/null @@ -1,26 +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.flavor; - -/** - * Matrix backends - */ -public enum BackEnum { - JVMMEM, - NETLIB_BLAS -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/flavor/MatrixFlavor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/flavor/MatrixFlavor.java b/core/src/main/java/org/apache/mahout/math/flavor/MatrixFlavor.java deleted file mode 100644 index e1d93f2..0000000 --- a/core/src/main/java/org/apache/mahout/math/flavor/MatrixFlavor.java +++ /dev/null @@ -1,82 +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.flavor; - -/** A set of matrix structure properties that I denote as "flavor" (by analogy to quarks) */ -public interface MatrixFlavor { - - /** - * Whether matrix is backed by a native system -- such as java memory, lapack/atlas, Magma etc. - */ - BackEnum getBacking(); - - /** - * Structure flavors - */ - TraversingStructureEnum getStructure() ; - - boolean isDense(); - - /** - * This default for {@link org.apache.mahout.math.DenseMatrix}-like structures - */ - MatrixFlavor DENSELIKE = new FlavorImpl(BackEnum.JVMMEM, TraversingStructureEnum.ROWWISE, true); - /** - * This is default flavor for {@link org.apache.mahout.math.SparseRowMatrix}-like. - */ - MatrixFlavor SPARSELIKE = new FlavorImpl(BackEnum.JVMMEM, TraversingStructureEnum.ROWWISE, false); - - /** - * This is default flavor for {@link org.apache.mahout.math.SparseMatrix}-like structures, i.e. sparse matrix blocks, - * where few, perhaps most, rows may be missing entirely. - */ - MatrixFlavor SPARSEROWLIKE = new FlavorImpl(BackEnum.JVMMEM, TraversingStructureEnum.SPARSEROWWISE, false); - - /** - * This is default flavor for {@link org.apache.mahout.math.DiagonalMatrix} and the likes. - */ - MatrixFlavor DIAGONALLIKE = new FlavorImpl(BackEnum.JVMMEM, TraversingStructureEnum.VECTORBACKED, false); - - final class FlavorImpl implements MatrixFlavor { - private BackEnum pBacking; - private TraversingStructureEnum pStructure; - private boolean pDense; - - public FlavorImpl(BackEnum backing, TraversingStructureEnum structure, boolean dense) { - pBacking = backing; - pStructure = structure; - pDense = dense; - } - - @Override - public BackEnum getBacking() { - return pBacking; - } - - @Override - public TraversingStructureEnum getStructure() { - return pStructure; - } - - @Override - public boolean isDense() { - return pDense; - } - } - -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/flavor/TraversingStructureEnum.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/flavor/TraversingStructureEnum.java b/core/src/main/java/org/apache/mahout/math/flavor/TraversingStructureEnum.java deleted file mode 100644 index 13c2cf4..0000000 --- a/core/src/main/java/org/apache/mahout/math/flavor/TraversingStructureEnum.java +++ /dev/null @@ -1,48 +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.flavor; - -/** STRUCTURE HINT */ -public enum TraversingStructureEnum { - - UNKNOWN, - - /** - * Backing vectors are directly available as row views. - */ - ROWWISE, - - /** - * Column vectors are directly available as column views. - */ - COLWISE, - - /** - * Only some row-wise vectors are really present (can use iterateNonEmpty). Corresponds to - * [[org.apache.mahout.math.SparseMatrix]]. - */ - SPARSEROWWISE, - - SPARSECOLWISE, - - SPARSEHASH, - - VECTORBACKED, - - BLOCKIFIED -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/function/DoubleDoubleFunction.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/function/DoubleDoubleFunction.java b/core/src/main/java/org/apache/mahout/math/function/DoubleDoubleFunction.java deleted file mode 100644 index 466ddd6..0000000 --- a/core/src/main/java/org/apache/mahout/math/function/DoubleDoubleFunction.java +++ /dev/null @@ -1,98 +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. - */ - -/* -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.function; - -/** - * Interface that represents a function object: a function that takes two arguments and returns a single value. - **/ -public abstract class DoubleDoubleFunction { - - /** - * Apply the function to the arguments and return the result - * - * @param arg1 a double for the first argument - * @param arg2 a double for the second argument - * @return the result of applying the function - */ - public abstract double apply(double arg1, double arg2); - - /** - * @return true iff f(x, 0) = x for any x - */ - public boolean isLikeRightPlus() { - return false; - } - - /** - * @return true iff f(0, y) = 0 for any y - */ - public boolean isLikeLeftMult() { - return false; - } - - /** - * @return true iff f(x, 0) = 0 for any x - */ - public boolean isLikeRightMult() { - return false; - } - - /** - * @return true iff f(x, 0) = f(0, y) = 0 for any x, y - */ - public boolean isLikeMult() { - return isLikeLeftMult() && isLikeRightMult(); - } - - /** - * @return true iff f(x, y) = f(y, x) for any x, y - */ - public boolean isCommutative() { - return false; - } - - /** - * @return true iff f(x, f(y, z)) = f(f(x, y), z) for any x, y, z - */ - public boolean isAssociative() { - return false; - } - - /** - * @return true iff f(x, y) = f(y, x) for any x, y AND f(x, f(y, z)) = f(f(x, y), z) for any x, y, z - */ - public boolean isAssociativeAndCommutative() { - return isAssociative() && isCommutative(); - } - - /** - * @return true iff f(0, 0) != 0 - */ - public boolean isDensifying() { - return apply(0.0, 0.0) != 0.0; - } -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/function/DoubleFunction.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/function/DoubleFunction.java b/core/src/main/java/org/apache/mahout/math/function/DoubleFunction.java deleted file mode 100644 index 7545154..0000000 --- a/core/src/main/java/org/apache/mahout/math/function/DoubleFunction.java +++ /dev/null @@ -1,48 +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.function; - -/* -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. -*/ - -/** - * Interface that represents a function object: a function that takes a single argument and returns a single value. - * @see org.apache.mahout.math.map - */ -public abstract class DoubleFunction { - - /** - * Apply the function to the argument and return the result - * - * @param x double for the argument - * @return the result of applying the function - */ - public abstract double apply(double x); - - public boolean isDensifying() { - return Math.abs(apply(0.0)) != 0.0; - } -} http://git-wip-us.apache.org/repos/asf/mahout/blob/49ad8cb4/core/src/main/java/org/apache/mahout/math/function/FloatFunction.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mahout/math/function/FloatFunction.java b/core/src/main/java/org/apache/mahout/math/function/FloatFunction.java deleted file mode 100644 index 94dfe32..0000000 --- a/core/src/main/java/org/apache/mahout/math/function/FloatFunction.java +++ /dev/null @@ -1,36 +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.function; - - -/** - * Interface that represents a function object: a function that takes a single argument and returns a single value. - * - */ -public interface FloatFunction { - - /** - * Applies a function to an argument. - * - * @param argument argument passed to the function. - * @return the result of the function. - */ - float apply(float argument); -}
