Line data Source code
1 : # include <stdlib.h>
2 : # include <stdint.h>
3 : # include <vector>
4 : # include <stdio.h>
5 : # include <iostream>
6 : # include <numeric>
7 : # include <string>
8 : # include <math.h>
9 : // # include <sys/stat.h>
10 : # include "../inc/header.h"
11 : # include "../inc/utils.h"
12 :
13 :
14 : // # include <unistd.h>
15 : // # include <sys/types.h>
16 :
17 0 : VDInt Cos_loss(const std::vector<data> &a, const std::vector<data> &b, size_t offset){
18 0 : VDInt result=0;
19 0 : data lambda = 32;
20 0 : for(int i=0; i<b.size();i++){
21 0 : result += (log(cosh(a[offset+i]/lambda))-log(cosh(b[i]/lambda))-tanh(b[i]/lambda)*(a[offset+i]/lambda-b[i]/lambda))/2;
22 : }
23 0 : return result;
24 : }
25 :
26 0 : VDInt Euclidean_loss(const std::vector<data> &a, const std::vector<data> &b, size_t offset)
27 : {
28 0 : VDInt result=0;
29 0 : data lambda = 8;
30 0 : for(int i=0; i<b.size();i++){
31 0 : result += (a[offset+i]/lambda-b[i]/lambda)*(a[offset+i]/lambda-b[i]/lambda);
32 : }
33 0 : return result;
34 : }
35 :
36 0 : VDInt KullbackLeibler_loss(const std::vector<data> &a, const std::vector<data> &b, size_t offset)
37 : {
38 0 : VDInt result=0;
39 0 : for(int i=0; i<b.size();i++){
40 0 : result += (a[offset+i]+1)*log((VDInt)(a[offset+i]+1)/((VDInt)b[i]+1));
41 : }
42 0 : return result;
43 : }
44 :
45 0 : VDInt Exponential_loss(const std::vector<data> &a, const std::vector<data> &b, size_t offset)
46 : {
47 0 : VDInt result=0;
48 0 : data lambda = 64;
49 0 : for(int i=0; i<b.size();i++){
50 0 : result += exp((VDInt)a[offset+i]/lambda)-exp((VDInt)b[i]/lambda)-(VDInt)(a[offset+i]/lambda-b[i]/lambda)*exp((VDInt)b[i]/lambda);
51 : }
52 0 : return result;
53 : }
54 :
55 0 : VDInt GKL_loss(const std::vector<data> &a, const std::vector<data> &b, size_t offset)
56 : {
57 0 : VDInt result=0;
58 0 : VDInt shift=1;
59 0 : data lambda = 32;
60 0 : for(int i=0; i<b.size();i++){
61 0 : result += (a[offset+i]/lambda+shift)*log((VDInt)(a[offset+i]/lambda+shift)/((VDInt)b[i]/lambda+shift))-(a[offset+i]/lambda-b[i]/lambda);
62 : }
63 0 : return result;
64 : }
65 :
66 : // uniquement pour des valeurs comprise entre 0 et 1
67 : /*
68 : float_t Logisitic_loss(const std::vector<float_t> &a, const std::vector<float_t> &b, size_t offset)
69 : {
70 : double result=0;
71 : for(int i=0; i<b.size();i++){
72 : result += a[offset+i]*log(a[offset+i]/(b[i]))-(1-a[offset+i])*log((1-a[offset+i])/(1-b[i]));
73 : }
74 : return result;
75 : }
76 : */
77 :
78 0 : VDInt ItakuraSaito_loss(const std::vector<data> &a, const std::vector<data> &b, size_t offset)
79 : {
80 0 : VDInt result=0;
81 0 : data lambda = 1;
82 0 : for(int i=0; i<b.size();i++){
83 0 : result += (a[offset+i]/lambda+1)/((VDInt)b[i]/lambda+1)-log((VDInt)(a[offset+i]/lambda+1)/((VDInt)b[i]/lambda+1))-1;
84 : }
85 0 : return result;
86 : }
87 :
88 0 : VDInt SoftPlus_loss(const std::vector<data> &a, const std::vector<data> &b, size_t offset)
89 : {
90 0 : VDInt result=0;
91 0 : data lambda = 16;
92 0 : for(int i=0; i<b.size();i++){
93 0 : result += log(1+exp(a[offset+i]/lambda)/((VDInt)1+exp(b[i]/lambda)))-(a[offset+i]/lambda-b[i]/lambda)*(exp(b[i]/lambda))/(1+exp(b[i]/lambda));
94 : }
95 0 : return result;
96 : }
97 :
98 0 : void compute_distance(std::vector<VDInt> & distances, std::vector<data> &datas, int nb_data,
99 : std::vector<data> ¢roid, int dimension, char divergence='E') {
100 0 : distances.resize(nb_data);
101 0 : for (size_t i = 0; i < nb_data; i++){
102 0 : if(divergence == 'E'){
103 : //std::cout<<"e";
104 0 : distances[i] = Euclidean_loss(datas, centroid, i * (size_t) dimension);
105 0 : }else if(divergence == 'K'){
106 : //std::cout<<"k";
107 0 : distances[i] = GKL_loss(datas, centroid, i * (size_t) dimension);
108 0 : }else if(divergence == 'X'){
109 : //std::cout<<"x";
110 0 : distances[i] = Exponential_loss(datas, centroid, i * (size_t) dimension);
111 0 : }else if(divergence == 'I'){
112 : //std::cout<<"i";
113 0 : distances[i] = ItakuraSaito_loss(datas, centroid, i * (size_t) dimension);
114 0 : }else if(divergence == 'S'){
115 : //std::cout<<"i";
116 0 : distances[i] = SoftPlus_loss(datas, centroid, i * (size_t) dimension);
117 0 : }else if(divergence == 'C'){
118 : //std::cout<<"i";
119 0 : distances[i] = Cos_loss(datas, centroid, i * (size_t) dimension);
120 : }else{
121 : //std::cout<<"."<<std::endl;
122 0 : distances[i] = Euclidean_loss(datas, centroid, i * (size_t) dimension);
123 : }
124 : }
125 : //std::cout<<std::endl;
126 0 : }
127 :
128 0 : void NNeighbors(std::vector<uint32_t> & result, int id_desc, int nb_data,
129 : int dimension, std::vector<data> & mat_data, std::vector<uint32_t> & ids,
130 : int limit_return, std::vector<VDInt> & distances, std::vector<data> &query_desc, char divergence, int verbose)
131 : {
132 : // Fais le calcul de distance entre un vecteur et tous une liste de vecteur (mat_data). Puis tri le point le plus proche de ce vecteur.
133 : // VR 18-9-17 : je me demande bien qui a mis ce test ici, on a l'air de dupliquer beaucoup de code a cause de cela, et sans doute de ne pas le tester du coup,
134 : // ce sont sans doute les memes fonctions qui font le jobs, mais cela me parait vraiment inquietant,
135 : // car les arguments pourrait changer quand meme
136 0 : if (id_desc > nb_data)
137 : {
138 0 : printf("Wrong id_query : %d, nb_data : %d \n", id_desc, nb_data);
139 0 : return;
140 : }
141 :
142 0 : if (id_desc >= 0)
143 : {
144 0 : uint64_t address = (uint64_t) id_desc * (uint64_t) dimension;
145 0 : for (int i = 0; i < dimension; i++)
146 0 : query_desc[i] = mat_data[address + i];
147 : }
148 :
149 0 : compute_distance(distances, mat_data, nb_data, query_desc, dimension, divergence);
150 :
151 0 : quick_sort<VDInt>(ids, distances, nb_data, verbose);
152 :
153 0 : result.resize(std::min<int>(limit_return, nb_data));
154 :
155 0 : for (int i = 0; i < limit_return && i < nb_data; i++)
156 0 : result[i] = ids[i];
157 : }
|