12
#include "../src/kissrandom.h"
13
#include "../src/annoylib.h"
20
int precision(int f=40, int n=1000000){
21
std::chrono::high_resolution_clock::time_point t_start, t_end;
23
std::default_random_engine generator;
24
std::normal_distribution<double> distribution(0.0, 1.0);
28
AnnoyIndex<int, double, Angular, Kiss32Random, AnnoyIndexMultiThreadedBuildPolicy> t = AnnoyIndex<int, double, Angular, Kiss32Random, AnnoyIndexMultiThreadedBuildPolicy>(f);
30
std::cout << "Building index ... be patient !!" << std::endl;
31
std::cout << "\"Trees that are slow to grow bear the best fruit\" (Moliere)" << std::endl;
35
for(int i=0; i<n; ++i){
36
double *vec = (double *) malloc( f * sizeof(double) );
38
for(int z=0; z<f; ++z){
39
vec[z] = (distribution(generator));
44
std::cout << "Loading objects ...\t object: "<< i+1 << "\tProgress:"<< std::fixed << std::setprecision(2) << (double) i / (double)(n + 1) * 100 << "%\r";
47
std::cout << std::endl;
48
std::cout << "Building index num_trees = 2 * num_features ...";
49
t_start = std::chrono::high_resolution_clock::now();
51
t_end = std::chrono::high_resolution_clock::now();
52
auto duration = std::chrono::duration_cast<std::chrono::seconds>( t_end - t_start ).count();
53
std::cout << " Done in "<< duration << " secs." << std::endl;
56
std::cout << "Saving index ...";
57
t.save("precision.tree");
58
std::cout << " Done" << std::endl;
63
std::vector<int> limits = {10, 100, 1000, 10000};
67
std::map<int, double> prec_sum;
68
std::map<int, double> time_sum;
69
std::vector<int> closest;
72
for(std::vector<int>::iterator it = limits.begin(); it!=limits.end(); ++it){
73
prec_sum[(*it)] = 0.0;
74
time_sum[(*it)] = 0.0;
78
for(int i=0; i<prec_n; ++i){
83
std::cout << "finding nbs for " << j << std::endl;
86
t.get_nns_by_item(j, K, n, &closest, nullptr);
88
std::vector<int> toplist;
89
std::vector<int> intersection;
91
for(std::vector<int>::iterator limit = limits.begin(); limit!=limits.end(); ++limit){
93
t_start = std::chrono::high_resolution_clock::now();
94
t.get_nns_by_item(j, (*limit), (size_t) -1, &toplist, nullptr);
95
t_end = std::chrono::high_resolution_clock::now();
96
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>( t_end - t_start ).count();
99
std::sort(closest.begin(), closest.end(), std::less<int>());
100
std::sort(toplist.begin(), toplist.end(), std::less<int>());
101
intersection.resize(std::max(closest.size(), toplist.size()));
102
std::vector<int>::iterator it_set = std::set_intersection(closest.begin(), closest.end(), toplist.begin(), toplist.end(), intersection.begin());
103
intersection.resize(it_set-intersection.begin());
106
int found = intersection.size();
107
double hitrate = found / (double) K;
108
prec_sum[(*limit)] += hitrate;
110
time_sum[(*limit)] += duration;
114
vector<int>().swap(intersection);
115
vector<int>().swap(toplist);
119
for(std::vector<int>::iterator limit = limits.begin(); limit!=limits.end(); ++limit){
120
std::cout << "limit: " << (*limit) << "\tprecision: "<< std::fixed << std::setprecision(2) << (100.0 * prec_sum[(*limit)] / (i + 1)) << "% \tavg. time: "<< std::fixed<< std::setprecision(6) << (time_sum[(*limit)] / (i + 1)) * 1e-04 << "s" << std::endl;
123
closest.clear(); vector<int>().swap(closest);
127
std::cout << "\nDone" << std::endl;
133
std::cout << "Annoy Precision C++ example" << std::endl;
134
std::cout << "Usage:" << std::endl;
135
std::cout << "(default) ./precision" << std::endl;
136
std::cout << "(using parameters) ./precision num_features num_nodes" << std::endl;
137
std::cout << std::endl;
140
void feedback(int f, int n){
141
std::cout<<"Runing precision example with:" << std::endl;
142
std::cout<<"num. features: "<< f << std::endl;
143
std::cout<<"num. nodes: "<< n << std::endl;
144
std::cout << std::endl;
148
int main(int argc, char **argv) {
158
precision(40, 1000000);