DiSMEC++
sparse.cpp
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 #include "model/sparse.h"
7 #include "spdlog/spdlog.h"
8 #include "utils/eigen_generic.h"
9 #include "utils/conversion.h"
10 
11 using namespace dismec;
12 using namespace dismec::model;
13 
14 namespace {
16  long check_positive(long v, const char* error_msg) {
17  if(v > 0) {
18  return v;
19  }
20  throw std::invalid_argument(error_msg);
21  }
22 }
23 
24 SparseModel::SparseModel(long num_features, long num_labels) :
25  SparseModel(num_features, PartialModelSpec{label_id_t{0}, num_labels, num_labels}){
26 
27 }
28 
29 SparseModel::SparseModel(long num_features, PartialModelSpec partial) :
30  Model(partial),
31  m_Weights(check_positive(partial.label_count, "Number of weight must be positive!")),
32  m_NumFeatures(num_features) {
33  for(auto& w : m_Weights) {
34  w.resize(num_features);
35  }
36 }
37 
38 
40  return m_NumFeatures;
41 }
42 
43 namespace {
44  struct PredictVisitor {
45  PredictVisitor(const Eigen::Ref<PredictionMatrix>& target, const std::vector<SparseRealVector>* weights) :
46  Target(target), Weights(weights) {
47 
48  }
50  for(int i = 0; i < ssize(*Weights); ++i) {
51  Target.col(i) = instances * (*Weights)[i];
52  }
53  }
54 
56  for(int i = 0; i < ssize(*Weights); ++i) {
57  Target.col(i) = instances * (*Weights)[i];
58  }
59  }
60 
62  for(int i = 0; i <ssize(*Weights); ++i) {
63  Target.col(i) = instances * (*Weights)[i];
64  }
65  }
66 
68  types::SparseColMajor<real_t> copy = instances;
69  for(int i = 0; i < ssize(*Weights); ++i) {
70  Target.col(i) = copy * (*Weights)[i];
71  }
72  }
73 
74  Eigen::Ref<PredictionMatrix> Target;
75  const std::vector<SparseRealVector>* Weights;
76  };
77 }
78 
80  PredictVisitor visitor(target, &m_Weights);
81  visit(visitor, instances);
82 }
83 
84 void SparseModel::get_weights_for_label_unchecked(label_id_t label, Eigen::Ref<DenseRealVector> target) const {
85  target = m_Weights.at(label.to_index());
86 }
87 
88 namespace {
90  SetWeightsVisitor(label_id_t label, Eigen::SparseVector<real_t>* target) :
91  Label(label), Target(target) {
92 
93  }
94 
95  void operator()(const GenericInVector::DenseRef& source) {
96  Target->setZero();
97  for(long i = 0; i < source.size(); ++i) {
98  if(abs(source.coeff(i)) > 0) {
99  Target->insert(i) = source.coeff(i);
100  }
101  }
102  }
103 
105  *Target = source;
106  }
107 
109  Eigen::SparseVector<real_t>* Target;
110  };
111 }
112 
114  SetWeightsVisitor visitor(label, &m_Weights.at(label.to_index()));
115  visit(visitor, weights);
116 }
Strong typedef for an int to signify a label id.
Definition: types.h:20
A model combines a set of weight with some meta-information about these weights.
Definition: model.h:63
Eigen::Ref< PredictionMatrix > PredictionMatrixOut
Definition: model.h:65
SparseModel(long num_features, long num_labels)
Definition: sparse.cpp:24
long num_features() const override
How many weights are in each weight vector, i.e. how many features should the input have.
Definition: sparse.cpp:39
void predict_scores_unchecked(const FeatureMatrixIn &instances, PredictionMatrixOut target) const override
Unchecked version of predict_scores().
Definition: sparse.cpp:79
void set_weights_for_label_unchecked(label_id_t label, const WeightVectorIn &weights) override
Unchecked version of set_weights_for_label().
Definition: sparse.cpp:113
std::vector< SparseRealVector > m_Weights
Definition: sparse.h:28
void get_weights_for_label_unchecked(label_id_t label, Eigen::Ref< DenseRealVector > target) const override
Unchecked version of get_weights_for_label().
Definition: sparse.cpp:84
constexpr T to_index() const
! Explicitly convert to an integer.
Definition: opaque_int.h:32
Eigen::Ref< SparseColMajor< T > > SparseColMajorRef
Eigen::Ref< SparseRowMajor< T > > SparseRowMajorRef
Eigen::Ref< DenseColMajor< T > > DenseColMajorRef
Eigen::Ref< DenseRowMajor< T > > DenseRowMajorRef
Eigen::Ref< DenseVector< T > > DenseRef
Eigen::Ref< SparseVector< T > > SparseRef
long check_positive(long v, const char *error_msg)
Definition: sparse.cpp:16
auto visit(F &&f, Variants &&... variants)
Definition: eigen_generic.h:95
Main namespace in which all types, classes, and functions are defined.
Definition: app.h:15
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
Eigen::Ref< PredictionMatrix > Target
Definition: sparse.cpp:74
void operator()(const GenericInMatrix::SparseColMajorRef &instances)
Definition: sparse.cpp:61
void operator()(const GenericInMatrix::DenseRowMajorRef &instances)
Definition: sparse.cpp:55
void operator()(const GenericInMatrix::DenseColMajorRef &instances)
Definition: sparse.cpp:49
void operator()(const GenericInMatrix::SparseRowMajorRef &instances)
Definition: sparse.cpp:67
PredictVisitor(const Eigen::Ref< PredictionMatrix > &target, const std::vector< SparseRealVector > *weights)
Definition: sparse.cpp:45
const std::vector< SparseRealVector > * Weights
Definition: sparse.cpp:75
void operator()(const GenericInVector::SparseRef &source)
Definition: sparse.cpp:104
void operator()(const GenericInVector::DenseRef &source)
Definition: sparse.cpp:95
SetWeightsVisitor(label_id_t label, Eigen::SparseVector< real_t > *target)
Definition: sparse.cpp:90
Eigen::SparseVector< real_t > * Target
Definition: sparse.cpp:109
Specifies how to interpret a weight matrix for a partial model.
Definition: model.h:22