| 75 | } |
| 76 | |
| 77 | virtual void separation_oracle ( |
| 78 | const long idx, |
| 79 | const matrix_type& current_solution, |
| 80 | scalar_type& loss, |
| 81 | feature_vector_type& psi |
| 82 | ) const |
| 83 | { |
| 84 | scalar_type best_val = -std::numeric_limits<scalar_type>::infinity(); |
| 85 | unsigned long best_idx = 0; |
| 86 | |
| 87 | // Figure out which label is the best. That is, what label maximizes |
| 88 | // LOSS(idx,y) + F(x,y). Note that y in this case is given by distinct_labels[i]. |
| 89 | for (unsigned long i = 0; i < distinct_labels.size(); ++i) |
| 90 | { |
| 91 | // Compute the F(x,y) part: |
| 92 | // perform: temp == dot(relevant part of current solution, samples[idx]) - current_bias |
| 93 | scalar_type temp = dot(rowm(current_solution, range(i*dims, (i+1)*dims-2)), samples[idx]) - current_solution((i+1)*dims-1); |
| 94 | |
| 95 | // Add the LOSS(idx,y) part: |
| 96 | if (labels[idx] != distinct_labels[i]) |
| 97 | temp += 1; |
| 98 | |
| 99 | // Now temp == LOSS(idx,y) + F(x,y). Check if it is the biggest we have seen. |
| 100 | if (temp > best_val) |
| 101 | { |
| 102 | best_val = temp; |
| 103 | best_idx = i; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | assign(psi, samples[idx]); |
| 108 | // add a constant -1 to account for the bias term |
| 109 | psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1))); |
| 110 | |
| 111 | offset_feature_vector(psi, dims*best_idx); |
| 112 | |
| 113 | if (distinct_labels[best_idx] == labels[idx]) |
| 114 | loss = 0; |
| 115 | else |
| 116 | loss = 1; |
| 117 | } |
| 118 | |
| 119 | private: |
| 120 | |