DiSMEC++
reg_sq_hinge_detail.h
Go to the documentation of this file.
1 // Copyright (c) 2021, Aalto University, developed by Erik Schultheis
2 // All rights reserved.
3 //
4 // SPDX-License-Identifier: MIT
5 
6 #ifndef DISMEC_REG_SQ_HINGE_DETAIL_H
7 #define DISMEC_REG_SQ_HINGE_DETAIL_H
8 
9 #include <vector>
10 #include "utils/conversion.h"
11 #include "matrix_types.h"
13 
14 namespace dismec {
15  namespace l2_reg_sq_hinge_detail {
16  template<class Derived>
17  inline void htd_sum_naive(const std::vector<int>& indices, Eigen::Ref<DenseRealVector> output,
18  const Eigen::EigenBase<Derived>& features, const DenseRealVector& costs,
19  const DenseRealVector& direction) {
20  for (auto index: indices) {
21  float factor = 2.f * features.derived().row(index).dot(direction) * costs.coeff(index);
22  output += factor * features.derived().row(index);
23  }
24  }
25 
26  template<int LOOK_AHEAD = 2>
27  inline void htd_sum(const std::vector<int>& indices, Eigen::Ref<DenseRealVector> output,
28  const SparseFeatures& features, const DenseRealVector& costs,
29  const DenseRealVector& direction) {
30  if (indices.empty())
31  return;
32 
33  const auto *val_ptr = features.valuePtr();
34  const auto *inner_ptr = features.innerIndexPtr();
35  const auto *outer_ptr = features.outerIndexPtr();
36 
37  long sm1 = ssize(indices) - 1;
38  for (long i = 0; i < ssize(indices); ++i) {
39  int index = indices[i];
40  int next_index = indices[std::min(i + LOOK_AHEAD, sm1)];
41  int next_id = outer_ptr[next_index];
42  __builtin_prefetch(&val_ptr[next_id], 0, 1);
43  __builtin_prefetch(&inner_ptr[next_id], 0, 1);
44 
45  FastSparseRowIter row_iter(features, index);
46  float factor = 0.f;
47  float cost_val = costs.coeff(index);
48  for (FastSparseRowIter it = row_iter; it; ++it) {
49  factor += it.value() * direction.coeff(it.col());
50  }
51  factor *= 2.f * cost_val;
52  for (FastSparseRowIter it = row_iter; it; ++it) {
53  output.coeffRef(it.col()) += it.value() * factor;
54  }
55  }
56  }
57 
58  inline void __attribute__((hot))
59  htd_sum_new(const std::vector<int>& indices, Eigen::Ref<DenseRealVector> output,
60  const SparseFeatures& features, const DenseRealVector& costs, const DenseRealVector& direction) {
61  const auto *val_ptr = features.valuePtr();
62  const auto *inner_ptr = features.innerIndexPtr();
63  const auto *outer_ptr = features.outerIndexPtr();
64  long sm1 = ssize(indices) - 1;
65 
66  for (long i = 0; i < ssize(indices); ++i) {
67  int index = indices[i];
68  int next_index = indices[std::min(i + 2, sm1)];
69  int next_id = outer_ptr[next_index];
70  __builtin_prefetch(&val_ptr[next_id], 0, 1);
71  __builtin_prefetch(&inner_ptr[next_id], 0, 1);
72 
73  float factor = 2.f * fast_dot(features, index, direction) * costs.coeff(index);
74  for (FastSparseRowIter it(features, index); it; ++it) {
75  output.coeffRef(it.col()) += it.value() * factor;
76  }
77  }
78  }
79 
82  template<typename Derived>
84  const Eigen::DenseBase<Derived>& xTw) {
85  real_t f = 0;
86  assert(xTw.size() == labels.size());
87  long num_labels = to_long(labels.size());
88  for (long i = 0; i < num_labels; ++i) {
89  real_t label = labels.coeff(i);
90  real_t d = 1.0 - label * xTw.coeff(i);
91  if (d > 0) {
92  real_t factor = cost.coeff(i);
93  f += factor * d * d;
94  }
95  }
96 
97  return f;
98  }
99  }
100 }
101 
102 #endif //DISMEC_REG_SQ_HINGE_DETAIL_H
This is an almost verbatim copy of the SparseFeatures::InnerIterator provided by Eigen.
real_t value_from_xTw(const DenseRealVector &cost, const BinaryLabelVector &labels, const Eigen::DenseBase< Derived > &xTw)
void htd_sum_naive(const std::vector< int > &indices, Eigen::Ref< DenseRealVector > output, const Eigen::EigenBase< Derived > &features, const DenseRealVector &costs, const DenseRealVector &direction)
void __attribute__((hot)) htd_sum_new(const std
void htd_sum(const std::vector< int > &indices, Eigen::Ref< DenseRealVector > output, const SparseFeatures &features, const DenseRealVector &costs, const DenseRealVector &direction)
Main namespace in which all types, classes, and functions are defined.
Definition: app.h:15
auto fast_dot(const Eigen::SparseMatrix< Scalar, Options, StorageIndex > &first, int row, const Eigen::MatrixBase< OtherDerived > &other) -> Scalar
constexpr auto ssize(const C &c) -> std::common_type_t< std::ptrdiff_t, std::make_signed_t< decltype(c.size())>>
signed size free function. Taken from https://en.cppreference.com/w/cpp/iterator/size
Definition: conversion.h:42
constexpr long to_long(T value)
Convert the given value to long, throwing an error if the conversion is not possible.
Definition: conversion.h:14
types::DenseVector< std::int8_t > BinaryLabelVector
Dense vector for storing binary labels.
Definition: matrix_types.h:68
types::DenseVector< real_t > DenseRealVector
Any dense, real values vector.
Definition: matrix_types.h:40
types::SparseRowMajor< real_t > SparseFeatures
Sparse Feature Matrix in Row Major format.
Definition: matrix_types.h:50
float real_t
The default type for floating point values.
Definition: config.h:17