summaryrefslogtreecommitdiff
path: root/example_extff/ff_example.cc
diff options
context:
space:
mode:
authorChris Dyer <cdyer@cab.ark.cs.cmu.edu>2012-10-11 23:13:12 -0400
committerChris Dyer <cdyer@cab.ark.cs.cmu.edu>2012-10-11 23:13:12 -0400
commitf49ebcba9974a60ec3df2b6c97c7048186a5954d (patch)
tree0d88a436699817809171159b718c1228aaea6082 /example_extff/ff_example.cc
parentc25a0afc5d50b47fc2ffa388d8e43a7b93f6f266 (diff)
example external feature function
Diffstat (limited to 'example_extff/ff_example.cc')
-rw-r--r--example_extff/ff_example.cc56
1 files changed, 56 insertions, 0 deletions
diff --git a/example_extff/ff_example.cc b/example_extff/ff_example.cc
new file mode 100644
index 00000000..51ebf364
--- /dev/null
+++ b/example_extff/ff_example.cc
@@ -0,0 +1,56 @@
+#include "ff.h"
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+// example of a "stateful" feature made available as an external library
+// This feature looks nodes and their daughters and fires an indicator based
+// on the arities of the rules involved.
+// (X (X a) b (X c)) - this is a 2 arity parent with children of 0 and 0 arity
+// so you get MAF_2_0_0=1
+class ParentChildrenArityFeatures : public FeatureFunction {
+ public:
+ ParentChildrenArityFeatures(const string& param) : fids(16, vector<int>(256, -1)) {
+ SetStateSize(1); // number of bytes extra state required by this Feature
+ }
+ virtual void FinalTraversalFeatures(const void* context,
+ SparseVector<double>* features) const {
+ // Goal always is arity 1, so there's no discriminative value of
+ // computing a feature
+ }
+ protected:
+ virtual void TraversalFeaturesImpl(const SentenceMetadata& smeta,
+ const Hypergraph::Edge& edge,
+ const std::vector<const void*>& ant_contexts,
+ FeatureVector* features,
+ FeatureVector* estimated_features,
+ void* context) const {
+ unsigned child_arity_code = 0;
+ for (unsigned j = 0; j < ant_contexts.size(); ++j) {
+ child_arity_code <<= 4;
+ child_arity_code |= *reinterpret_cast<const unsigned char*>(ant_contexts[j]);
+ }
+ int& fid = fids[edge.Arity()][child_arity_code]; // reference!
+ if (fid < 0) {
+ ostringstream feature_string;
+ feature_string << "MAF_" << edge.Arity();
+ for (unsigned j = 0; j < ant_contexts.size(); ++j)
+ feature_string << '_' <<
+ static_cast<int>(*reinterpret_cast<const unsigned char*>(ant_contexts[j]));
+ fid = FD::Convert(feature_string.str());
+ }
+ features->set_value(fid, 1.0);
+ *reinterpret_cast<unsigned char*>(context) = edge.Arity(); // save state
+ }
+ private:
+ mutable vector<vector<int> > fids;
+};
+
+// IMPORTANT: this function must be implemented by any external FF library
+// if your library has multiple features, you can use str to configure things
+extern "C" FeatureFunction* create_ff(const string& str) {
+ return new ParentChildrenArityFeatures(str);
+}
+
+