aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/features/closenessfeature.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'searchlib/src/vespa/searchlib/features/closenessfeature.cpp')
-rw-r--r--searchlib/src/vespa/searchlib/features/closenessfeature.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/searchlib/src/vespa/searchlib/features/closenessfeature.cpp b/searchlib/src/vespa/searchlib/features/closenessfeature.cpp
new file mode 100644
index 00000000000..f6b289bfd16
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/features/closenessfeature.cpp
@@ -0,0 +1,110 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/fastos/fastos.h>
+#include <vespa/log/log.h>
+LOG_SETUP(".features.closenessfeature");
+#include <vespa/searchlib/fef/properties.h>
+#include "closenessfeature.h"
+#include "utils.h"
+
+using namespace search::fef;
+
+namespace search {
+namespace features {
+
+ClosenessExecutor::ClosenessExecutor(feature_t maxDistance, feature_t scaleDistance) :
+ FeatureExecutor(),
+ _maxDistance(maxDistance),
+ _logCalc(maxDistance, scaleDistance)
+{
+}
+
+void
+ClosenessExecutor::execute(MatchData & match)
+{
+ feature_t distance = *match.resolveFeature(inputs()[0]);
+ feature_t closeness = std::max(1 - (distance / _maxDistance), (feature_t)0);
+ *match.resolveFeature(outputs()[0]) = closeness;
+ *match.resolveFeature(outputs()[1]) = _logCalc.get(distance);
+}
+
+
+// Polar Earth radius r = 6356.8 km
+// Polar Earth diameter = 2 * pi * r = 39940.952 km
+// 1 diameter = 39940.952 km = 360 degrees = 360 * 1000000 microdegrees
+// -> 1 km = 9013.30536007 microdegrees
+
+ClosenessBlueprint::ClosenessBlueprint() :
+ Blueprint("closeness"),
+ _maxDistance(9013305.0), // default value (about 250 km)
+ _scaleDistance(5.0*9013.305), // default value (about 5 km)
+ _halfResponse(1)
+{
+}
+
+void
+ClosenessBlueprint::visitDumpFeatures(const IIndexEnvironment &,
+ IDumpFeatureVisitor &) const
+{
+}
+
+bool
+ClosenessBlueprint::setup(const IIndexEnvironment & env,
+ const search::fef::ParameterList & params)
+{
+ // params[0] = attribute name
+ Property p = env.getProperties().lookup(getName(), "maxDistance");
+ if (p.found()) {
+ _maxDistance = util::strToNum<feature_t>(p.get());
+ }
+ p = env.getProperties().lookup(getName(), "halfResponse");
+ bool useHalfResponse = false;
+ if (p.found()) {
+ _halfResponse = util::strToNum<feature_t>(p.get());
+ useHalfResponse = true;
+ }
+ // sanity checks:
+ if (_maxDistance < 1) {
+ LOG(warning, "Invalid %s.maxDistance = %g, using 1.0",
+ getName().c_str(), (double)_maxDistance);
+ _maxDistance = 1.0;
+ }
+ if (_halfResponse < 1) {
+ LOG(warning, "Invalid %s.halfResponse = %g, using 1.0",
+ getName().c_str(), (double)_halfResponse);
+ _halfResponse = 1.0;
+ }
+ if (_halfResponse >= _maxDistance / 2) {
+ feature_t newResponse = (_maxDistance / 2) - 1;
+ LOG(warning, "Invalid %s.halfResponse = %g, using %g ((%s.maxDistance / 2) - 1)",
+ getName().c_str(), (double)_halfResponse, (double)newResponse, getName().c_str());
+ _halfResponse = newResponse;
+ }
+
+ if (useHalfResponse) {
+ _scaleDistance = LogarithmCalculator::getScale(_halfResponse, _maxDistance);
+ }
+
+
+ defineInput("distance(" + params[0].getValue() + ")");
+ describeOutput("out", "The closeness of the document (linear)");
+ describeOutput("logscale", "The closeness of the document (logarithmic shape)");
+
+ return true;
+}
+
+Blueprint::UP
+ClosenessBlueprint::createInstance() const
+{
+ return Blueprint::UP(new ClosenessBlueprint());
+}
+
+FeatureExecutor::LP
+ClosenessBlueprint::createExecutor(const IQueryEnvironment &) const
+{
+ return FeatureExecutor::LP(new ClosenessExecutor(_maxDistance, _scaleDistance));
+}
+
+
+} // namespace features
+} // namespace search