12 #ifndef MLPACK_METHODS_LMNN_CONSTRAINTS_IMPL_HPP 13 #define MLPACK_METHODS_LMNN_CONSTRAINTS_IMPL_HPP 21 template<
typename MetricType>
24 const arma::Row<size_t>& labels,
30 size_t minCount = arma::min(arma::histc(labels, arma::unique(labels)));
34 Log::Fatal <<
"Constraints::Constraints(): One of the class contains only " 35 << minCount <<
" instances, but value of k is " << k <<
" " 36 <<
"(k should be < " << minCount <<
")!" << std::endl;
40 template<
typename MetricType>
42 const arma::mat& distances,
43 arma::Mat<size_t>& neighbors,
44 const arma::vec& norms)
47 if (neighbors.n_rows == 1)
52 for (
size_t i = 0; i < neighbors.n_cols; ++i)
54 for (
size_t start = 0; start < neighbors.n_rows - 1; start++)
56 size_t end = start + 1;
57 while (distances(start, i) == distances(end, i) &&
58 end < neighbors.n_rows)
61 if (end == neighbors.n_rows)
68 arma::Col<size_t> newNeighbors =
69 neighbors.col(i).subvec(start, end - 1);
70 arma::uvec indices = arma::conv_to<arma::uvec>::from(newNeighbors);
72 arma::uvec order = arma::sort_index(norms.elem(indices));
73 neighbors.col(i).subvec(start, end - 1) =
74 newNeighbors.elem(order);
81 template<
typename MetricType>
83 const arma::mat& dataset,
84 const arma::Row<size_t>& labels,
85 const arma::vec& norms)
93 arma::Mat<size_t> neighbors;
96 for (
size_t i = 0; i < uniqueLabels.n_cols; ++i)
100 knn.
Train(dataset.cols(indexSame[i]));
101 knn.
Search(k, neighbors, distances);
105 ReorderResults(distances, neighbors, norms);
108 for (
size_t j = 0; j < neighbors.n_elem; ++j)
109 neighbors(j) = indexSame[i].at(neighbors(j));
112 outputMatrix.cols(indexSame[i]) = neighbors;
118 template<
typename MetricType>
120 const arma::mat& dataset,
121 const arma::Row<size_t>& labels,
122 const arma::vec& norms,
124 const size_t batchSize)
127 Precalculate(labels);
129 arma::mat subDataset = dataset.cols(begin, begin + batchSize - 1);
130 arma::Row<size_t> sublabels = labels.cols(begin, begin + batchSize - 1);
135 arma::Mat<size_t> neighbors;
139 arma::uvec subIndexSame;
141 for (
size_t i = 0; i < uniqueLabels.n_cols; ++i)
144 subIndexSame = arma::find(sublabels == uniqueLabels[i]);
148 knn.
Train(dataset.cols(indexSame[i]));
149 knn.
Search(subDataset.cols(subIndexSame), k, neighbors, distances);
153 ReorderResults(distances, neighbors, norms);
156 for (
size_t j = 0; j < neighbors.n_elem; ++j)
157 neighbors(j) = indexSame[i].at(neighbors(j));
160 outputMatrix.cols(begin + subIndexSame) = neighbors;
165 template<
typename MetricType>
167 const arma::mat& dataset,
168 const arma::Row<size_t>& labels,
169 const arma::vec& norms)
172 Precalculate(labels);
177 arma::Mat<size_t> neighbors;
180 for (
size_t i = 0; i < uniqueLabels.n_cols; ++i)
184 knn.
Train(dataset.cols(indexDiff[i]));
185 knn.
Search(dataset.cols(indexSame[i]), k, neighbors, distances);
189 ReorderResults(distances, neighbors, norms);
192 for (
size_t j = 0; j < neighbors.n_elem; ++j)
193 neighbors(j) = indexDiff[i].at(neighbors(j));
196 outputMatrix.cols(indexSame[i]) = neighbors;
202 template<
typename MetricType>
204 arma::mat& outputDistance,
205 const arma::mat& dataset,
206 const arma::Row<size_t>& labels,
207 const arma::vec& norms)
210 Precalculate(labels);
215 arma::Mat<size_t> neighbors;
218 for (
size_t i = 0; i < uniqueLabels.n_cols; ++i)
222 knn.
Train(dataset.cols(indexDiff[i]));
223 knn.
Search(dataset.cols(indexSame[i]), k, neighbors, distances);
227 ReorderResults(distances, neighbors, norms);
230 for (
size_t j = 0; j < neighbors.n_elem; ++j)
231 neighbors(j) = indexDiff[i].at(neighbors(j));
234 outputNeighbors.cols(indexSame[i]) = neighbors;
235 outputDistance.cols(indexSame[i]) = distances;
241 template<
typename MetricType>
243 const arma::mat& dataset,
244 const arma::Row<size_t>& labels,
245 const arma::vec& norms,
247 const size_t batchSize)
250 Precalculate(labels);
252 arma::mat subDataset = dataset.cols(begin, begin + batchSize - 1);
253 arma::Row<size_t> sublabels = labels.cols(begin, begin + batchSize - 1);
258 arma::Mat<size_t> neighbors;
262 arma::uvec subIndexSame;
264 for (
size_t i = 0; i < uniqueLabels.n_cols; ++i)
267 subIndexSame = arma::find(sublabels == uniqueLabels[i]);
271 knn.
Train(dataset.cols(indexDiff[i]));
272 knn.
Search(subDataset.cols(subIndexSame), k, neighbors, distances);
276 ReorderResults(distances, neighbors, norms);
279 for (
size_t j = 0; j < neighbors.n_elem; ++j)
280 neighbors(j) = indexDiff[i].at(neighbors(j));
283 outputMatrix.cols(begin + subIndexSame) = neighbors;
289 template<
typename MetricType>
291 arma::mat& outputDistance,
292 const arma::mat& dataset,
293 const arma::Row<size_t>& labels,
294 const arma::vec& norms,
296 const size_t batchSize)
299 Precalculate(labels);
301 arma::mat subDataset = dataset.cols(begin, begin + batchSize - 1);
302 arma::Row<size_t> sublabels = labels.cols(begin, begin + batchSize - 1);
307 arma::Mat<size_t> neighbors;
311 arma::uvec subIndexSame;
313 for (
size_t i = 0; i < uniqueLabels.n_cols; ++i)
316 subIndexSame = arma::find(sublabels == uniqueLabels[i]);
320 knn.
Train(dataset.cols(indexDiff[i]));
321 knn.
Search(subDataset.cols(subIndexSame), k, neighbors, distances);
325 ReorderResults(distances, neighbors, norms);
328 for (
size_t j = 0; j < neighbors.n_elem; ++j)
329 neighbors(j) = indexDiff[i].at(neighbors(j));
332 outputNeighbors.cols(begin + subIndexSame) = neighbors;
333 outputDistance.cols(begin + subIndexSame) = distances;
339 template<
typename MetricType>
341 arma::mat& outputDistance,
342 const arma::mat& dataset,
343 const arma::Row<size_t>& labels,
344 const arma::vec& norms,
345 const arma::uvec& points,
346 const size_t numPoints)
349 Precalculate(labels);
354 arma::Mat<size_t> neighbors;
358 arma::uvec subIndexSame;
360 for (
size_t i = 0; i < uniqueLabels.n_cols; ++i)
363 subIndexSame = arma::find(labels.cols(points.head(numPoints)) ==
368 knn.
Train(dataset.cols(indexDiff[i]));
369 knn.
Search(dataset.cols(points.elem(subIndexSame)),
370 k, neighbors, distances);
374 ReorderResults(distances, neighbors, norms);
377 for (
size_t j = 0; j < neighbors.n_elem; ++j)
378 neighbors(j) = indexDiff[i].at(neighbors(j));
381 outputNeighbors.cols(points.elem(subIndexSame)) = neighbors;
382 outputDistance.cols(points.elem(subIndexSame)) = distances;
388 template<
typename MetricType>
390 const arma::mat& dataset,
391 const arma::Row<size_t>& labels,
392 const arma::vec& norms)
395 Precalculate(labels);
397 size_t N = dataset.n_cols;
399 arma::Mat<size_t> impostors(k, dataset.n_cols);
400 Impostors(impostors, dataset, labels, norms);
402 arma::Mat<size_t> targetNeighbors(k, dataset.n_cols);;
405 outputMatrix = arma::Mat<size_t>(3, k * k * N , arma::fill::zeros);
407 for (
size_t i = 0, r = 0; i < N; ++i)
409 for (
size_t j = 0; j < k; ++j)
411 for (
size_t l = 0; l < k; l++, r++)
414 outputMatrix(0, r) = i;
415 outputMatrix(1, r) = targetNeighbors(j, i);
416 outputMatrix(2, r) = impostors(l, i);
422 template<
typename MetricType>
424 const arma::Row<size_t>& labels)
430 uniqueLabels = arma::unique(labels);
432 indexSame.resize(uniqueLabels.n_elem);
433 indexDiff.resize(uniqueLabels.n_elem);
435 for (
size_t i = 0; i < uniqueLabels.n_elem; ++i)
438 indexSame[i] = arma::find(labels == uniqueLabels[i]);
439 indexDiff[i] = arma::find(labels != uniqueLabels[i]);
442 precalculated =
true;
static MLPACK_EXPORT util::PrefixedOutStream Fatal
Prints fatal messages prefixed with [FATAL], then terminates the program.
Definition: log.hpp:90
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
void Train(MatType referenceSet)
Set the reference set to a new reference set, and build a tree if necessary.
Definition: neighbor_search_impl.hpp:320
The NeighborSearch class is a template class for performing distance-based neighbor searches...
Definition: neighbor_search.hpp:88
Interface for generating distance based constraints on a given dataset, provided corresponding true l...
Definition: constraints.hpp:31
void Impostors(arma::Mat< size_t > &outputMatrix, const arma::mat &dataset, const arma::Row< size_t > &labels, const arma::vec &norms)
Calculates k differently labeled nearest neighbors for each datapoint and writes them back to passed ...
Definition: constraints_impl.hpp:166
void Triplets(arma::Mat< size_t > &outputMatrix, const arma::mat &dataset, const arma::Row< size_t > &labels, const arma::vec &norms)
Generate triplets {i, j, l} for each datapoint i and writes back generated triplets to matrix passed...
Definition: constraints_impl.hpp:389
Constraints(const arma::mat &dataset, const arma::Row< size_t > &labels, const size_t k)
Constructor for creating a Constraints instance.
Definition: constraints_impl.hpp:22
void TargetNeighbors(arma::Mat< size_t > &outputMatrix, const arma::mat &dataset, const arma::Row< size_t > &labels, const arma::vec &norms)
Calculates k similar labeled nearest neighbors and stores them into the passed matrix.
Definition: constraints_impl.hpp:82
void Search(const MatType &querySet, const size_t k, arma::Mat< size_t > &neighbors, arma::mat &distances)
For each point in the query set, compute the nearest neighbors and store the output in the given matr...
Definition: neighbor_search_impl.hpp:389