inline void closestColumnsAndDistancesShortcut( const MappedMatrix& inMatrix, const MappedColumnVector& inVector, FunctionHandle &inDist, RandomAccessIterator ioFirst, RandomAccessIterator ioLast) { // Sorted in the order of expected use if (inDist.funcPtr() == funcPtr<squared_dist_norm2>()) closestColumnsAndDistances(inMatrix, inVector, squaredDistNorm2, ioFirst, ioLast); else if (inDist.funcPtr() == funcPtr<dist_norm2>()) closestColumnsAndDistances(inMatrix, inVector, distNorm2, ioFirst, ioLast); else if (inDist.funcPtr() == funcPtr<dist_norm1>()) closestColumnsAndDistances(inMatrix, inVector, distNorm1, ioFirst, ioLast); else if (inDist.funcPtr() == funcPtr<dist_angle>()) closestColumnsAndDistances(inMatrix, inVector, distAngle, ioFirst, ioLast); else if (inDist.funcPtr() == funcPtr<dist_tanimoto>()) closestColumnsAndDistances(inMatrix, inVector, distTanimoto, ioFirst, ioLast); else closestColumnsAndDistances(inMatrix, inVector, inDist, ioFirst, ioLast); }
/** * @brief Compute the minimum distance between a vector and any column of a * matrix * * This function calls a user-supplied function, for which it does not do * garbage collection. It is therefore meant to be called only constantly many * times before control is returned to the backend. */ AnyType closest_column::run(AnyType& args) { MappedMatrix M = args[0].getAs<MappedMatrix>(); MappedColumnVector x = args[1].getAs<MappedColumnVector>(); FunctionHandle dist = args[2].getAs<FunctionHandle>() .unsetFunctionCallOptions(FunctionHandle::GarbageCollectionAfterCall); std::tuple<Index, double> result; // For performance, we cheat here: For the following four distance // functions, we take a special shortcut // FIXME: FunctionHandle should be tuned so that this shortcut no longer // impacts performance by more than, say, ~10%. if (dist.funcPtr() == funcPtr<squared_dist_norm1>()) result = closestColumnAndDistance(M, x, squaredDistNorm1); else if (dist.funcPtr() == funcPtr<squared_dist_norm2>()) result = closestColumnAndDistance(M, x, squaredDistNorm2); else if (dist.funcPtr() == funcPtr<squared_angle>()) result = closestColumnAndDistance(M, x, squaredAngle); else if (dist.funcPtr() == funcPtr<squared_tanimoto>()) result = closestColumnAndDistance(M, x, squaredTanimoto); else result = closestColumnAndDistance(M, x, dist); AnyType tuple; return tuple << static_cast<int16_t>(std::get<0>(result)) << std::get<1>(result); }