Darwin  1.10(beta)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
drwnFeatureMaps.h
1 /******************************************************************************
2 ** DARWIN: A FRAMEWORK FOR MACHINE LEARNING RESEARCH AND DEVELOPMENT
3 ** Distributed under the terms of the BSD license (see the LICENSE file)
4 ** Copyright (c) 2007-2015, Stephen Gould
5 ** All rights reserved.
6 **
7 ******************************************************************************
8 ** FILENAME: drwnFeatureMaps.h
9 ** AUTHOR(S): Stephen Gould <stephen.gould@anu.edu.au>
10 **
11 *****************************************************************************/
12 
13 #pragma once
14 
15 #include <cstdlib>
16 #include <vector>
17 #include <cmath>
18 
19 using namespace std;
20 
21 #define DRWN_UNROLL_FEATURE_MAP_LOOPS
22 
23 //
24 // classless feature mappings ----------------------------------------------
25 //
26 
27 // drwnFeatureMap ----------------------------------------------------------
39 
40 class drwnFeatureMap : public drwnTypeable, public drwnCloneable {
41  protected:
42  int _nFeatures;
43 
44  public:
46  drwnFeatureMap() : _nFeatures(0) { /* do nothing */ }
48  drwnFeatureMap(int nFeatures) : _nFeatures(nFeatures) { /* do nothing */ }
50  virtual ~drwnFeatureMap() { /* do nothing */ }
51 
52  virtual drwnFeatureMap *clone() const = 0;
53 
55  int numFeatures() const { return _nFeatures; }
57  virtual int numParameters() const = 0;
58 
60  virtual void initialize(int nFeatures) {
61  _nFeatures = nFeatures;
62  }
63 
65  virtual vector<double> operator()(const vector<double>& x) const = 0;
66 
68  virtual double dot(const vector<double>& theta, const vector<double>& x) const {
69  vector<double> phi((*this)(x));
70  double v = 0.0;
71  for (unsigned i = 0; i < phi.size(); i++) {
72  v += phi[i] * theta[i];
73  }
74  return v;
75  }
76 
78  virtual void mac(vector<double>& theta, const vector<double>& x, double alpha) const {
79  const vector<double> phi((*this)(x));
80  for (unsigned i = 0; i < phi.size(); i++) {
81  theta[i] += alpha * phi[i];
82  }
83  }
84 };
85 
86 // drwnIdentityFeatureMap ---------------------------------------------------
88 
90  public:
91  drwnIdentityFeatureMap() : drwnFeatureMap() { /* do nothing */ }
92  drwnIdentityFeatureMap(int nFeatures) : drwnFeatureMap(nFeatures) { /* do nothing */ }
93  ~drwnIdentityFeatureMap() { /* do nothing */ }
94 
95  // type and cloning
96  const char *type () const { return "drwnIdentityFeatureMap"; }
97  drwnIdentityFeatureMap *clone() const { return new drwnIdentityFeatureMap(*this); }
98 
100  int numParameters() const { return _nFeatures; }
101 
103  vector<double> operator()(const vector<double>& x) const {
104  return x;
105  }
106 
108  double dot(const vector<double>& theta, const vector<double>& x) const {
109  return Eigen::Map<const VectorXd>(&theta[0],
110  theta.size()).dot(Eigen::Map<const VectorXd>(&x[0], x.size()));
111  }
112 
114  void mac(vector<double>& theta, const vector<double>& x, double alpha) const {
115  Eigen::Map<VectorXd>(&theta[0], theta.size()) += alpha *
116  Eigen::Map<const VectorXd>(&x[0], x.size());
117  }
118 };
119 
120 // drwnBiasFeatureMap ------------------------------------------------------
122 
124  public:
125  drwnBiasFeatureMap() : drwnFeatureMap() { /* do nothing */ }
126  drwnBiasFeatureMap(int nFeatures) : drwnFeatureMap(nFeatures) { /* do nothing */ }
127  ~drwnBiasFeatureMap() { /* do nothing */ }
128 
129  // type and cloning
130  const char *type () const { return "drwnBiasFeatureMap"; }
131  drwnBiasFeatureMap *clone() const { return new drwnBiasFeatureMap(*this); }
132 
134  int numParameters() const { return _nFeatures + 1; }
135 
137  vector<double> operator()(const vector<double>& x) const {
138  vector<double> phi(x.size() + 1);
139  copy(x.begin(), x.end(), phi.begin());
140  phi.back() = 1.0;
141  return phi;
142  }
143 
145  double dot(const vector<double>& theta, const vector<double>& x) const {
146  return theta.back() +
147  Eigen::Map<const VectorXd>(&theta[0],
148  theta.size() - 1).dot(Eigen::Map<const VectorXd>(&x[0], x.size()));
149  }
150 
152  void mac(vector<double>& theta, const vector<double>& x, double alpha) const {
153  Eigen::Map<VectorXd>(&theta[0], theta.size() - 1) += alpha *
154  Eigen::Map<const VectorXd>(&x[0], x.size());
155  theta.back() += alpha;
156  }
157 };
158 
159 // drwnSquareFeatureMap ----------------------------------------------------
163 
165  public:
166  drwnSquareFeatureMap() : drwnFeatureMap() { /* do nothing */ }
167  drwnSquareFeatureMap(int nFeatures) : drwnFeatureMap(nFeatures) { /* do nothing */ }
168  ~drwnSquareFeatureMap() { /* do nothing */ }
169 
170  // type and cloning
171  const char *type () const { return "drwnSquareFeatureMap"; }
172  drwnSquareFeatureMap *clone() const { return new drwnSquareFeatureMap(*this); }
173 
175  int numParameters() const { return 2 * _nFeatures + 1; }
176 
178  vector<double> operator()(const vector<double>& x) const {
179  vector<double> phi(2 * x.size() + 1);
180  copy(x.begin(), x.end(), phi.begin());
181  for (unsigned i = 0; i < x.size(); i++) {
182  phi[x.size() + i] = M_SQRT1_2 * (x[i] * x[i] - 1.0);
183  }
184  phi.back() = 1.0;
185  return phi;
186  }
187 
189  double dot(const vector<double>& theta, const vector<double>& x) const {
190  double v = theta.back();
191  vector<double>::const_iterator it = theta.begin();
192  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
193  v += (*it) * (*ix);
194  }
195  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
196  v += M_SQRT1_2 * (*it) * ((*ix) * (*ix) - 1.0);
197  }
198  return v;
199  }
200 
202  void mac(vector<double>& theta, const vector<double>& x, double alpha) const {
203  Eigen::Map<ArrayXd>(&theta[0], _nFeatures) += alpha *
204  Eigen::Map<const ArrayXd>(&x[0], x.size());
205  Eigen::Map<ArrayXd>(&theta[_nFeatures], _nFeatures) += M_SQRT1_2 * alpha *
206  (Eigen::Map<const ArrayXd>(&x[0], x.size()).array().square() - 1.0);
207  theta.back() += alpha;
208  }
209 };
210 
211 // drwnQuadraticFeatureMap -------------------------------------------------
215 
217  public:
218  drwnQuadraticFeatureMap() : drwnFeatureMap() { /* do nothing */ }
219  drwnQuadraticFeatureMap(int nFeatures) : drwnFeatureMap(nFeatures) { /* do nothing */ }
220  ~drwnQuadraticFeatureMap() { /* do nothing */ }
221 
222  // type and cloning
223  const char *type () const { return "drwnQuadraticFeatureMap"; }
224  drwnQuadraticFeatureMap *clone() const { return new drwnQuadraticFeatureMap(*this); }
225 
227  int numParameters() const { return (_nFeatures + 3) * _nFeatures / 2 + 1; }
228 
230  vector<double> operator()(const vector<double>& x) const {
231  vector<double> phi(2 * x.size() + 1);
232  copy(x.begin(), x.end(), phi.begin());
233  int indx = x.size();
234  for (unsigned i = 0; i < x.size(); i++) {
235  for (unsigned j = 0; j < i; j++) {
236  phi[indx++] = x[i] * x[j];
237  }
238  phi[indx++] = M_SQRT1_2 * (x[i] * x[i] - 1.0);
239  }
240  phi.back() = 1.0;
241  return phi;
242  }
243 
245  double dot(const vector<double>& theta, const vector<double>& x) const {
246  double v = theta.back();
247  vector<double>::const_iterator it = theta.begin();
248  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
249  v += (*it) * (*ix);
250  }
251  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
252  for (vector<double>::const_iterator jx = x.begin(); jx != ix; ++jx, ++it) {
253  v += (*it) * (*ix) * (*jx);
254  }
255  v += M_SQRT1_2 * (*it) * ((*ix) * (*ix) - 1.0);
256  }
257  return v;
258  }
259 
261  void mac(vector<double>& theta, const vector<double>& x, double alpha) const {
262  vector<double>::iterator it = theta.begin();
263  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
264  (*it) += alpha * (*ix);
265  }
266  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
267  for (vector<double>::const_iterator jx = x.begin(); jx != ix; ++jx, ++it) {
268  (*it) += alpha * (*ix) * (*jx);
269  }
270  (*it) += alpha * M_SQRT1_2 * ((*ix) * (*ix) - 1.0);
271  }
272  theta.back() += alpha;
273  }
274 };
275 
276 //
277 // classful feature mappings -----------------------------------------------
278 //
279 
280 // drwnJointFeatureMap -----------------------------------------------------
292 
294  protected:
296  int _nClasses;
297 
298  public:
300  drwnJointFeatureMap() : _nFeatures(0), _nClasses(0) { /* do nothing */ }
302  drwnJointFeatureMap(int nFeatures, int nClasses) :
303  _nFeatures(nFeatures), _nClasses(nClasses) { /* do nothing */ }
305  virtual ~drwnJointFeatureMap() { /* do nothing */ }
306 
307  virtual drwnJointFeatureMap *clone() const = 0;
308 
310  int numFeatures() const { return _nFeatures; }
312  int numClasses() const { return _nClasses; }
314  virtual int numParameters() const = 0;
315 
317  virtual void initialize(int nFeatures, int nClasses) {
318  _nFeatures = nFeatures; _nClasses = nClasses;
319  }
320 
322  virtual vector<double> operator()(const vector<double>& x, int y) const = 0;
323 
325  virtual vector<double> operator()(const vector<double>& x) const {
326  vector<double> phi(numParameters());
327  for (int y = 0; y < _nClasses; y++) {
328  vector<double> phi_y((*this)(x, y));
329  for (unsigned i = 0; i < phi.size(); i++) {
330  phi[i] += phi_y[i];
331  }
332  }
333  return phi;
334  }
335 
337  virtual double dot(const vector<double>& theta, const vector<double>& x, int y) const {
338  vector<double> phi((*this)(x, y));
339  double v = 0.0;
340  for (unsigned i = 0; i < phi.size(); i++) {
341  v += phi[i] * theta[i];
342  }
343  return v;
344  }
345 
347  double dot(const vector<double>& theta, const vector<double>& x) const {
348  double v = 0.0;
349  for (int y = 0; y < _nClasses; y++) {
350  v += dot(theta, x, y);
351  }
352  return v;
353  }
354 
356  virtual void mac(vector<double>& theta, const vector<double>& x, double alpha, int y) const {
357  const vector<double> phi((*this)(x, y));
358  for (unsigned i = 0; i < phi.size(); i++) {
359  theta[i] += alpha * phi[i];
360  }
361  }
362 
364  virtual void mac(vector<double>& theta, const vector<double>& x, const vector<double>& alpha) const {
365  for (int y = 0; y < _nClasses; y++) {
366  const vector<double> phi((*this)(x, y));
367  for (unsigned i = 0; i < phi.size(); i++) {
368  theta[i] += alpha[y] * phi[i];
369  }
370  }
371  }
372 };
373 
374 // drwnIdentityJointFeatureMap ----------------------------------------------
379 
381 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
382  protected:
383  int _nFeaturesDiv4;
384  int _nFeaturesMod4;
385 #endif
386 
387  public:
389 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
390  _nFeaturesDiv4 = 0;
391  _nFeaturesMod4 = 0;
392 #endif
393  }
394  drwnIdentityJointFeatureMap(int nFeatures, int nClasses) :
395  drwnJointFeatureMap(nFeatures, nClasses) {
396 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
397  _nFeaturesDiv4 = nFeatures / 4;
398  _nFeaturesMod4 = nFeatures % 4;
399 #endif
400  }
401  ~drwnIdentityJointFeatureMap() { /* do nothing */ }
402 
403  // type and cloning
404  const char *type () const { return "drwnIdentityJointFeatureMap"; }
406 
408  int numParameters() const { return std::max(_nFeatures * (_nClasses - 1), 0); }
409 
410 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
411  void initialize(int nFeatures, int nClasses) {
413  _nFeatures = nFeatures; _nClasses = nClasses;
414  _nFeaturesDiv4 = nFeatures / 4;
415  _nFeaturesMod4 = nFeatures % 4;
416  }
417 #endif
418 
420  vector<double> operator()(const vector<double>& x, int y) const {
421  vector<double> phi(numParameters(), 0.0);
422  if (y != _nClasses - 1) {
423  copy(x.begin(), x.end(), phi.begin() + y * _nFeatures);
424  }
425  return phi;
426  }
427 
429  vector<double> operator()(const vector<double>& x) const {
430  vector<double> phi(numParameters());
431  for (int y = 0; y < _nClasses - 1; y++) {
432  copy(x.begin(), x.end(), phi.begin() + y * _nFeatures);
433  }
434  return phi;
435  }
436 
438  double dot(const vector<double>& theta, const vector<double>& x, int y) const {
439  if (y == _nClasses - 1) return 0.0;
440  double v = 0.0;
441 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
442  const double *it = &theta[y * _nFeatures];
443  const double *ix = &x[0];
444  for (int i = _nFeaturesDiv4; i != 0; i--) {
445  v += it[0] * ix[0] + it[1] * ix[1] + it[2] * ix[2] + it[3] * ix[3];
446  it += 4; ix += 4;
447  }
448  for (int i = 0; i < _nFeaturesMod4; i++, ++it, ++ix) {
449  v += (*it) * (*ix);
450  }
451 #else
452  vector<double>::const_iterator it = theta.begin() + y * _nFeatures;
453  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
454  v += (*it) * (*ix);
455  }
456 #endif
457  return v;
458  }
459 
461  double dot(const vector<double>& theta, const vector<double>& x) const {
462  double v = 0.0;
463  vector<double>::const_iterator it = theta.begin();
464  for (int y = 0; y < _nClasses - 1; y++) {
465  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
466  v += (*it) * (*ix);
467  }
468  }
469  return v;
470  }
471 
473  void mac(vector<double>& theta, const vector<double>& x, double alpha, int y) const {
474  if (y == _nClasses - 1) return;
475 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
476  double *it = &theta[y * _nFeatures];
477  const double *ix = &x[0];
478  for (int i = _nFeaturesDiv4; i != 0; i--) {
479  it[0] += alpha * ix[0];
480  it[1] += alpha * ix[1];
481  it[2] += alpha * ix[2];
482  it[3] += alpha * ix[3];
483  it += 4; ix += 4;
484  }
485  for (int i = 0; i < _nFeaturesMod4; i++, ++it, ++ix) {
486  (*it) += alpha * (*ix);
487  }
488 #else
489  vector<double>::iterator it = theta.begin() + y * _nFeatures;
490  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
491  (*it) += alpha * (*ix);
492  }
493 #endif
494  }
495 
497  void mac(vector<double>& theta, const vector<double>& x, const vector<double>& alpha) const {
498  vector<double>::iterator it = theta.begin();
499  for (int y = 0; y < _nClasses - 1; y++) {
500  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
501  (*it) += alpha[y] * (*ix);
502  }
503  }
504  }
505 };
506 
507 // drwnBiasJointFeatureMap -------------------------------------------------
511 
513 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
514  protected:
515  int _nFeaturesDiv4;
516  int _nFeaturesMod4;
517 #endif
518 
519  public:
521 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
522  _nFeaturesDiv4 = 0;
523  _nFeaturesMod4 = 0;
524 #endif
525  }
526  drwnBiasJointFeatureMap(int nFeatures, int nClasses) :
527  drwnJointFeatureMap(nFeatures, nClasses) {
528 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
529  _nFeaturesDiv4 = nFeatures / 4;
530  _nFeaturesMod4 = nFeatures % 4;
531 #endif
532  }
533  ~drwnBiasJointFeatureMap() { /* do nothing */ }
534 
535  // type and cloning
536  const char *type () const { return "drwnBiasJointFeatureMap"; }
537  drwnBiasJointFeatureMap *clone() const { return new drwnBiasJointFeatureMap(*this); }
538 
540  int numParameters() const { return std::max((_nFeatures + 1) * (_nClasses - 1), 0); }
541 
542 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
543  void initialize(int nFeatures, int nClasses) {
545  _nFeatures = nFeatures; _nClasses = nClasses;
546  _nFeaturesDiv4 = nFeatures / 4;
547  _nFeaturesMod4 = nFeatures % 4;
548  }
549 #endif
550 
552  vector<double> operator()(const vector<double>& x, int y) const {
553  vector<double> phi(numParameters(), 0.0);
554  if (y != _nClasses - 1) {
555  copy(x.begin(), x.end(), phi.begin() + y * (_nFeatures + 1));
556  phi[y * (_nFeatures + 1) + _nFeatures] = 1.0;
557  }
558  return phi;
559  }
560 
562  vector<double> operator()(const vector<double>& x) const {
563  vector<double> phi(numParameters());
564  vector<double>::iterator it = phi.begin();
565  for (int y = 0; y < _nClasses - 1; y++) {
566  copy(x.begin(), x.end(), it);
567  *(it += _nFeatures)++ = 1.0;
568  }
569  return phi;
570  }
571 
573  double dot(const vector<double>& theta, const vector<double>& x, int y) const {
574  if (y == _nClasses - 1) return 0.0;
575  double v = 0.0;
576 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
577  const double *it = &theta[y * (_nFeatures + 1)];
578  const double *ix = &x[0];
579  for (int i = _nFeaturesDiv4; i != 0; i--) {
580  v += it[0] * ix[0] + it[1] * ix[1] + it[2] * ix[2] + it[3] * ix[3];
581  it += 4; ix += 4;
582  }
583  for (int i = 0; i < _nFeaturesMod4; i++, ++it, ++ix) {
584  v += (*it) * (*ix);
585  }
586 #else
587  vector<double>::const_iterator it = theta.begin() + y * (_nFeatures + 1);
588  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
589  v += (*it) * (*ix);
590  }
591 #endif
592  v += (*it);
593  return v;
594  }
595 
597  double dot(const vector<double>& theta, const vector<double>& x) const {
598  double v = 0.0;
599  vector<double>::const_iterator it = theta.begin();
600  for (int y = 0; y < _nClasses - 1; y++) {
601  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
602  v += (*it) * (*ix);
603  }
604  v += (*it++);
605  }
606  return v;
607  }
608 
610  void mac(vector<double>& theta, const vector<double>& x, double alpha, int y) const {
611  if (y == _nClasses - 1) return;
612 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
613  double *it = &theta[y * (_nFeatures + 1)];
614  const double *ix = &x[0];
615  for (int i = _nFeaturesDiv4; i != 0; i--) {
616  it[0] += alpha * ix[0];
617  it[1] += alpha * ix[1];
618  it[2] += alpha * ix[2];
619  it[3] += alpha * ix[3];
620  it += 4; ix += 4;
621  }
622  for (int i = 0; i < _nFeaturesMod4; i++, ++it, ++ix) {
623  (*it) += alpha * (*ix);
624  }
625 #else
626  vector<double>::iterator it = theta.begin() + y * (_nFeatures + 1);
627  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
628  (*it) += alpha * (*ix);
629  }
630 #endif
631  (*it) += alpha;
632  }
633 
635  void mac(vector<double>& theta, const vector<double>& x, const vector<double>& alpha) const {
636  vector<double>::iterator it = theta.begin();
637  for (int y = 0; y < _nClasses - 1; y++) {
638  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
639  (*it) += alpha[y] * (*ix);
640  }
641  (*it++) += alpha[y];
642  }
643  }
644 };
645 
646 // drwnSquareJointFeatureMap -----------------------------------------------
651 
653 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
654  protected:
655  int _nFeaturesDiv4;
656  int _nFeaturesMod4;
657 #endif
658 
659  public:
661 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
662  _nFeaturesDiv4 = 0;
663  _nFeaturesMod4 = 0;
664 #endif
665  }
666  drwnSquareJointFeatureMap(int nFeatures, int nClasses) :
667  drwnJointFeatureMap(nFeatures, nClasses) {
668 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
669  _nFeaturesDiv4 = nFeatures / 4;
670  _nFeaturesMod4 = nFeatures % 4;
671 #endif
672  }
673  ~drwnSquareJointFeatureMap() { /* do nothing */ }
674 
675  // type and cloning
676  const char *type () const { return "drwnSquareJointFeatureMap"; }
678 
680  int numParameters() const { return std::max((2 * _nFeatures + 1) * (_nClasses - 1), 0); }
681 
682 #ifdef DRWN_UNROLL_FEATURE_MAP_LOOPS
683  void initialize(int nFeatures, int nClasses) {
685  _nFeatures = nFeatures; _nClasses = nClasses;
686  _nFeaturesDiv4 = nFeatures / 4;
687  _nFeaturesMod4 = nFeatures % 4;
688  }
689 #endif
690 
692  vector<double> operator()(const vector<double>& x, int y) const {
693  vector<double> phi(numParameters(), 0.0);
694  if (y != _nClasses - 1) {
695  vector<double>::iterator jt = phi.begin() + y * (2 * _nFeatures + 1);
696  for (vector<double>::const_iterator it = x.begin(); it != x.end(); ++it, ++jt) {
697  (*jt) = (*it);
698  }
699  for (vector<double>::const_iterator it = x.begin(); it != x.end(); ++it, ++jt) {
700  (*jt) = M_SQRT1_2 * ((*it) * (*it) - 1.0);
701  }
702  (*jt) = 1.0;
703  }
704  return phi;
705  }
706 
708  vector<double> operator()(const vector<double>& x) const {
709  vector<double> phi(numParameters());
710  vector<double>::iterator jt = phi.begin();
711  for (vector<double>::const_iterator it = x.begin(); it != x.end(); ++it, ++jt) {
712  (*jt) = (*it);
713  }
714  for (vector<double>::const_iterator it = x.begin(); it != x.end(); ++it, ++jt) {
715  (*jt) = M_SQRT1_2 * ((*it) * (*it) - 1.0);
716  }
717  (*jt) = 1.0;
718 
719  for (int y = 1; y < _nClasses - 1; y++) {
720  copy(jt - (2 * _nFeatures + 1), jt, jt + 1);
721  jt += (2 * _nFeatures + 1);
722  }
723  return phi;
724  }
725 
727  double dot(const vector<double>& theta, const vector<double>& x, int y) const {
728  if (y == _nClasses - 1) return 0.0;
729 #if 1
730  double v = 0.0;
731  vector<double>::const_iterator it = theta.begin() + y * (2 * _nFeatures + 1);
732  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
733  v += (*it) * (*ix);
734  }
735  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
736  v += M_SQRT1_2 * (*it) * ((*ix) * (*ix) - 1.0);
737  }
738  v += (*it);
739 
740  return v;
741 #else
742  return Eigen::Map<const VectorXd>(&theta[y * (2 * _nFeatures + 1)],
743  _nFeatures).dot(Eigen::Map<const VectorXd>(&x[0], _nFeatures)) +
744  Eigen::Map<const VectorXd>(&theta[y * (2 * _nFeatures + 1) + _nFeatures],
745  _nFeatures).dot(M_SQRT1_2 *
746  (Eigen::Map<const VectorXd>(&x[0], x.size()).array().square().array() - 1.0)) +
747  theta[y * (2 * _nFeatures + 1) + 2 * _nFeatures];
748 #endif
749  }
750 
752  double dot(const vector<double>& theta, const vector<double>& x) const {
753  double v = 0.0;
754  vector<double>::const_iterator it = theta.begin();
755  for (int y = 0; y < _nClasses - 1; y++) {
756  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
757  v += (*it) * (*ix);
758  }
759  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
760  v += M_SQRT1_2 * (*it) * ((*ix) * (*ix) - 1.0);
761  }
762  v += (*it++);
763  }
764  return v;
765  }
766 
768  void mac(vector<double>& theta, const vector<double>& x, double alpha, int y) const {
769  if (y == _nClasses - 1) return;
770  vector<double>::iterator it = theta.begin() + y * (2 * _nFeatures + 1);
771  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
772  (*it) += alpha * (*ix);
773  }
774  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
775  (*it) += M_SQRT1_2 * alpha * ((*ix) * (*ix) - 1.0);
776  }
777  (*it) += alpha;
778  }
779 
781  void mac(vector<double>& theta, const vector<double>& x, const vector<double>& alpha) const {
782  vector<double>::iterator it = theta.begin();
783  for (int y = 0; y < _nClasses - 1; y++) {
784 #if 1
785  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
786  (*it) += alpha[y] * (*ix);
787  }
788  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
789  (*it) += M_SQRT1_2 * alpha[y] * ((*ix) * (*ix) - 1.0);
790  }
791  (*it++) += alpha[y];
792 #else
793  Eigen::Map<VectorXd>(&theta[y * (2 * _nFeatures + 1)], _nFeatures) += alpha[y] *
794  Eigen::Map<const VectorXd>(&x[0], x.size());
795  Eigen::Map<VectorXd>(&theta[y * (2 * _nFeatures + 1) + _nFeatures], _nFeatures) += M_SQRT1_2 * alpha[y] *
796  (Eigen::Map<const VectorXd>(&x[0], x.size()).array().square().array() - 1.0);
797  theta[y * (2 * _nFeatures + 1) + 2 * _nFeatures] += alpha[y];
798 #endif
799  }
800  }
801 };
802 
803 // drwnQuadraticJointFeatureMap --------------------------------------------
805 
807  public:
808  drwnQuadraticJointFeatureMap() : drwnJointFeatureMap() { /* do nothing */ }
809  drwnQuadraticJointFeatureMap(int nFeatures, int nClasses) :
810  drwnJointFeatureMap(nFeatures, nClasses) { /* do nothing */ }
811  ~drwnQuadraticJointFeatureMap() { /* do nothing */ }
812 
813  // type and cloning
814  const char *type () const { return "drwnQuadraticJointFeatureMap"; }
816 
818  int numParameters() const { return std::max(((_nFeatures + 3) * _nFeatures / 2 + 1) *
819  (_nClasses - 1), 0); }
820 
822  vector<double> operator()(const vector<double>& x, int y) const {
823  vector<double> phi(numParameters(), 0.0);
824  if (y != _nClasses - 1) {
825  vector<double>::iterator it = phi.begin() + y * ((_nFeatures + 3) * _nFeatures / 2 + 1);
826  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
827  (*it) = (*ix);
828  }
829  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
830  for (vector<double>::const_iterator jx = x.begin(); jx != ix; ++jx, ++it) {
831  (*it) = (*ix) * (*jx);
832  }
833  (*it) = M_SQRT1_2 * ((*ix) * (*ix) - 1.0);
834  }
835  (*it) = 1.0;
836  }
837  return phi;
838  }
839 
841  vector<double> operator()(const vector<double>& x) const {
842  vector<double> phi(numParameters());
843  vector<double>::iterator it = phi.begin();
844  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
845  (*it) = (*ix);
846  }
847  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
848  for (vector<double>::const_iterator jx = x.begin(); jx != ix; ++jx, ++it) {
849  (*it) = (*ix) * (*jx);
850  }
851  (*it) = M_SQRT1_2 * ((*ix) * (*ix) - 1.0);
852  }
853  (*it) = 1.0;
854 
855  vector<double>::iterator jt = ++it;
856  while (jt != phi.end()) {
857  copy(phi.begin(), it, jt);
858  jt += it - phi.begin();
859  }
860  return phi;
861  }
862 
864  double dot(const vector<double>& theta, const vector<double>& x, int y) const {
865  if (y == _nClasses - 1) return 0.0;
866  double v = 0.0;
867  vector<double>::const_iterator it = theta.begin() +
868  y * ((_nFeatures + 3) * _nFeatures / 2 + 1);
869  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
870  v += (*it) * (*ix);
871  }
872  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
873  for (vector<double>::const_iterator jx = x.begin(); jx != ix; ++jx, ++it) {
874  v += (*it) * (*ix) * (*jx);
875  }
876  v += M_SQRT1_2 * (*it) * ((*ix) * (*ix) - 1.0);
877  }
878  v += (*it);
879 
880  return v;
881  }
882 
884  double dot(const vector<double>& theta, const vector<double>& x) const {
885  double v = 0.0;
886  vector<double>::const_iterator it = theta.begin();
887  for (int y = 0; y < _nClasses - 1; y++) {
888  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
889  v += (*it) * (*ix);
890  }
891  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
892  for (vector<double>::const_iterator jx = x.begin(); jx != ix; ++jx, ++it) {
893  v += (*it) * (*ix) * (*jx);
894  }
895  v += M_SQRT1_2 * (*it) * ((*ix) * (*ix) - 1.0);
896  }
897  v += (*it++);
898  }
899  return v;
900  }
901 
903  void mac(vector<double>& theta, const vector<double>& x, double alpha, int y) const {
904  if (y == _nClasses - 1) return;
905  vector<double>::iterator it = theta.begin() + y * ((_nFeatures + 3) * _nFeatures / 2 + 1);
906  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
907  (*it) += alpha * (*ix);
908  }
909  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
910  for (vector<double>::const_iterator jx = x.begin(); jx != ix; ++jx, ++it) {
911  (*it) += alpha * (*ix) * (*jx);
912  }
913  (*it) += M_SQRT1_2 * alpha * ((*ix) * (*ix) - 1.0);
914  }
915  (*it) += alpha;
916  }
917 
919  void mac(vector<double>& theta, const vector<double>& x, const vector<double>& alpha) const {
920  vector<double>::iterator it = theta.begin();
921  for (int y = 0; y < _nClasses - 1; y++) {
922  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
923  (*it) += alpha[y] * (*ix);
924  }
925  for (vector<double>::const_iterator ix = x.begin(); ix != x.end(); ++ix, ++it) {
926  for (vector<double>::const_iterator jx = x.begin(); jx != ix; ++jx, ++it) {
927  (*it) += alpha[y] * (*ix) * (*jx);
928  }
929  (*it) += M_SQRT1_2 * alpha[y] * ((*ix) * (*ix) - 1.0);
930  }
931  (*it++) += alpha[y];
932  }
933  }
934 };
935 
int _nFeatures
number of input features
Definition: drwnFeatureMaps.h:42
void mac(vector< double > &theta, const vector< double > &x, const vector< double > &alpha) const
multiply-accumulate
Definition: drwnFeatureMaps.h:497
double dot(const vector< double > &theta, const vector< double > &x) const
dot product
Definition: drwnFeatureMaps.h:245
drwnJointFeatureMap()
default constructor
Definition: drwnFeatureMaps.h:300
drwnFeatureMap()
default constructor
Definition: drwnFeatureMaps.h:46
double dot(const vector< double > &theta, const vector< double > &x) const
returns the dot product (default behaviour is very inefficient)
Definition: drwnFeatureMaps.h:347
int numClasses() const
returns the number of classes
Definition: drwnFeatureMaps.h:312
vector< double > operator()(const vector< double > &x) const
feature vector summed over y
Definition: drwnFeatureMaps.h:841
vector< double > operator()(const vector< double > &x) const
feature vector
Definition: drwnFeatureMaps.h:230
vector< double > operator()(const vector< double > &x, int y) const
feature vector for given y
Definition: drwnFeatureMaps.h:552
int numParameters() const
returns the number of features in the output space
Definition: drwnFeatureMaps.h:134
double dot(const vector< double > &theta, const vector< double > &x) const
dot product
Definition: drwnFeatureMaps.h:752
int numParameters() const
returns the number of features in the (joint) output space
Definition: drwnFeatureMaps.h:540
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnFeatureMaps.h:404
double dot(const vector< double > &theta, const vector< double > &x) const
dot product
Definition: drwnFeatureMaps.h:597
void mac(vector< double > &theta, const vector< double > &x, double alpha) const
multiply-accumulate
Definition: drwnFeatureMaps.h:202
interface for an object that returns its own type as a string
Definition: drwnInterfaces.h:25
drwnIdentityFeatureMap * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnFeatureMaps.h:97
int numParameters() const
returns the number of features in the (joint) output space
Definition: drwnFeatureMaps.h:408
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnFeatureMaps.h:130
Defines the interface for a joint feature mapping .
Definition: drwnFeatureMaps.h:293
void mac(vector< double > &theta, const vector< double > &x, double alpha) const
multiply-accumulate
Definition: drwnFeatureMaps.h:114
void mac(vector< double > &theta, const vector< double > &x, double alpha, int y) const
multiply-accumulate
Definition: drwnFeatureMaps.h:903
virtual void mac(vector< double > &theta, const vector< double > &x, double alpha, int y) const
provides multiply-accumulate operation (default behaviour is very inefficient)
Definition: drwnFeatureMaps.h:356
void mac(vector< double > &theta, const vector< double > &x, const vector< double > &alpha) const
multiply-accumulate
Definition: drwnFeatureMaps.h:919
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnFeatureMaps.h:676
drwnQuadraticFeatureMap * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnFeatureMaps.h:224
void mac(vector< double > &theta, const vector< double > &x, double alpha) const
multiply-accumulate
Definition: drwnFeatureMaps.h:152
virtual void mac(vector< double > &theta, const vector< double > &x, const vector< double > &alpha) const
provides multiply-accumulate operation (default behaviour is very inefficient)
Definition: drwnFeatureMaps.h:364
virtual vector< double > operator()(const vector< double > &x) const
returns (default behaviour is very inefficient)
Definition: drwnFeatureMaps.h:325
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnFeatureMaps.h:814
virtual double dot(const vector< double > &theta, const vector< double > &x, int y) const
returns the dot product (default behaviour is very inefficient)
Definition: drwnFeatureMaps.h:337
void mac(vector< double > &theta, const vector< double > &x, double alpha, int y) const
multiply-accumulate
Definition: drwnFeatureMaps.h:610
Same as drwnSquareJointFeatureMap but adds cross-terms.
Definition: drwnFeatureMaps.h:806
int numFeatures() const
returns the number of features in the input space
Definition: drwnFeatureMaps.h:310
Same as drwnIdentityJointFeatureMap but adds a square term for each feature i.e., ...
Definition: drwnFeatureMaps.h:652
Includes a copy of each feature from the input space for each class other than the last...
Definition: drwnFeatureMaps.h:380
vector< double > operator()(const vector< double > &x) const
feature vector summed over y
Definition: drwnFeatureMaps.h:562
double dot(const vector< double > &theta, const vector< double > &x) const
dot product
Definition: drwnFeatureMaps.h:884
int numParameters() const
returns the number of features in the (joint) output space
Definition: drwnFeatureMaps.h:818
interface for cloning object (i.e., virtual copy constructor)
Definition: drwnInterfaces.h:36
virtual void initialize(int nFeatures, int nClasses)
initialize number of classes and number of features
Definition: drwnFeatureMaps.h:317
vector< double > operator()(const vector< double > &x) const
feature vector
Definition: drwnFeatureMaps.h:178
vector< double > operator()(const vector< double > &x, int y) const
feature vector for given y
Definition: drwnFeatureMaps.h:692
drwnIdentityJointFeatureMap * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnFeatureMaps.h:405
double dot(const vector< double > &theta, const vector< double > &x, int y) const
dot product
Definition: drwnFeatureMaps.h:727
Augments input feature vector with square of each feature (normalized so that if input is zero mean a...
Definition: drwnFeatureMaps.h:216
double dot(const vector< double > &theta, const vector< double > &x) const
dot product
Definition: drwnFeatureMaps.h:461
double dot(const vector< double > &theta, const vector< double > &x) const
dot product
Definition: drwnFeatureMaps.h:189
drwnFeatureMap(int nFeatures)
construct with known number of input features
Definition: drwnFeatureMaps.h:48
double dot(const vector< double > &theta, const vector< double > &x, int y) const
dot product
Definition: drwnFeatureMaps.h:573
virtual void initialize(int nFeatures)
initialize number of (intput) features
Definition: drwnFeatureMaps.h:60
vector< double > operator()(const vector< double > &x, int y) const
joint feature vector for given class
Definition: drwnFeatureMaps.h:420
drwnBiasFeatureMap * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnFeatureMaps.h:131
drwnBiasJointFeatureMap * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnFeatureMaps.h:537
vector< double > operator()(const vector< double > &x, int y) const
feature vector for given y
Definition: drwnFeatureMaps.h:822
Augments input feature vector with square of each feature (normalized so that if input is zero mean a...
Definition: drwnFeatureMaps.h:164
virtual void mac(vector< double > &theta, const vector< double > &x, double alpha) const
provides multiply-accumulate operation (default behaviour is very inefficient)
Definition: drwnFeatureMaps.h:78
double dot(const vector< double > &theta, const vector< double > &x, int y) const
dot product
Definition: drwnFeatureMaps.h:438
void mac(vector< double > &theta, const vector< double > &x, double alpha, int y) const
multiply-accumulate
Definition: drwnFeatureMaps.h:473
int numParameters() const
returns the number of features in the output space
Definition: drwnFeatureMaps.h:175
void mac(vector< double > &theta, const vector< double > &x, double alpha, int y) const
multiply-accumulate
Definition: drwnFeatureMaps.h:768
void mac(vector< double > &theta, const vector< double > &x, double alpha) const
multiply-accumulate
Definition: drwnFeatureMaps.h:261
void mac(vector< double > &theta, const vector< double > &x, const vector< double > &alpha) const
multiply-accumulate
Definition: drwnFeatureMaps.h:635
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnFeatureMaps.h:171
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnFeatureMaps.h:223
virtual double dot(const vector< double > &theta, const vector< double > &x) const
returns the dot product (default behaviour is very inefficient)
Definition: drwnFeatureMaps.h:68
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnFeatureMaps.h:536
int _nClasses
number of class labels
Definition: drwnFeatureMaps.h:296
Augments input feature vector with 1 (i.e., to allow for a bias weight)
Definition: drwnFeatureMaps.h:123
int numParameters() const
returns the number of features in the (joint) output space
Definition: drwnFeatureMaps.h:680
double dot(const vector< double > &theta, const vector< double > &x, int y) const
dot product
Definition: drwnFeatureMaps.h:864
vector< double > operator()(const vector< double > &x) const
feature vector
Definition: drwnFeatureMaps.h:137
Copies input feature space to output feature space.
Definition: drwnFeatureMaps.h:89
double dot(const vector< double > &theta, const vector< double > &x) const
dot product
Definition: drwnFeatureMaps.h:145
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnFeatureMaps.h:96
int numFeatures() const
returns the number of features in the input space
Definition: drwnFeatureMaps.h:55
drwnQuadraticJointFeatureMap * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnFeatureMaps.h:815
Same as drwnIdentityJointFeatureMap but adds a bias term for each class i.e., .
Definition: drwnFeatureMaps.h:512
drwnSquareFeatureMap * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnFeatureMaps.h:172
vector< double > operator()(const vector< double > &x) const
feature vector
Definition: drwnFeatureMaps.h:103
void mac(vector< double > &theta, const vector< double > &x, const vector< double > &alpha) const
multiply-accumulate
Definition: drwnFeatureMaps.h:781
int _nFeatures
number of input features
Definition: drwnFeatureMaps.h:295
virtual ~drwnFeatureMap()
destructor
Definition: drwnFeatureMaps.h:50
int numParameters() const
returns the number of features in the output space
Definition: drwnFeatureMaps.h:100
Defines the interface for a feature mapping .
Definition: drwnFeatureMaps.h:40
virtual ~drwnJointFeatureMap()
destructor
Definition: drwnFeatureMaps.h:305
drwnSquareJointFeatureMap * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnFeatureMaps.h:677
double dot(const vector< double > &theta, const vector< double > &x) const
dot product
Definition: drwnFeatureMaps.h:108
vector< double > operator()(const vector< double > &x) const
joint feature vector summed over classes
Definition: drwnFeatureMaps.h:429
drwnJointFeatureMap(int nFeatures, int nClasses)
construct with known number of input features and classes
Definition: drwnFeatureMaps.h:302
vector< double > operator()(const vector< double > &x) const
feature vector summed over y
Definition: drwnFeatureMaps.h:708
int numParameters() const
returns the number of features in the output space
Definition: drwnFeatureMaps.h:227