1 #include "reductions.h"
2
3 const int autoconstant = 524267083;
4
5 struct autolink {
6 uint32_t d; // degree of the polynomial
7 uint32_t stride_shift;
8 };
9
10 template <bool is_learn>
predict_or_learn(autolink & b,LEARNER::base_learner & base,example & ec)11 void predict_or_learn(autolink& b, LEARNER::base_learner& base, example& ec)
12 {
13 base.predict(ec);
14 float base_pred = ec.pred.scalar;
15 // add features of label
16 ec.indices.push_back(autolink_namespace);
17 float sum_sq = 0;
18 for (size_t i = 0; i < b.d; i++)
19 if (base_pred != 0.)
20 {
21 feature f = { base_pred, (uint32_t) (autoconstant + (i << b.stride_shift)) };
22 ec.atomics[autolink_namespace].push_back(f);
23 sum_sq += base_pred*base_pred;
24 base_pred *= ec.pred.scalar;
25 }
26 ec.total_sum_feat_sq += sum_sq;
27
28 if (is_learn)
29 base.learn(ec);
30 else
31 base.predict(ec);
32
33 ec.atomics[autolink_namespace].erase();
34 ec.indices.pop();
35 ec.total_sum_feat_sq -= sum_sq;
36 }
37
autolink_setup(vw & all)38 LEARNER::base_learner* autolink_setup(vw& all)
39 {
40 if (missing_option<size_t, true>(all, "autolink", "create link function with polynomial d"))
41 return NULL;
42
43 autolink& data = calloc_or_die<autolink>();
44 data.d = (uint32_t)all.vm["autolink"].as<size_t>();
45 data.stride_shift = all.reg.stride_shift;
46
47 LEARNER::learner<autolink>& ret =
48 init_learner(&data, setup_base(all), predict_or_learn<true>, predict_or_learn<false>);
49
50 return make_base(ret);
51 }
52