/**
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
**/
#include"pivots.h"
void prnstats (Index S);
Index build (char *dbname, int n, int *argc, char ***argv)
{ nn *tabla;
int i,j,k;
if (*argc < 1)
{ fprintf (stderr,"Usage: PIVOTS \n");
exit(1);
}
tabla = malloc (sizeof(nn));
tabla->descr = malloc (strlen(dbname)+1);
strcpy (tabla->descr,dbname);
tabla->coords = atoi((*argv)[0]);
tabla->n = openDB(dbname);
if (n && (n < tabla->n)) tabla-> n = n;
if (tabla->n < tabla->coords) tabla->coords = tabla->n;
tabla->piv = malloc (tabla->coords * sizeof(Obj));
tabla->nums = malloc (tabla->n * tabla->coords * sizeof(Tdist));
*argc -= 1; *argv += 1;
k=0; i=0;
while (k< tabla->coords)
{ tabla->piv[i] = ++k;
i++;
}
k=0; i=0;
while (k < tabla->n)
{ Obj obj = ++k;
for (j=0;jcoords;j++)
tabla->nums[i*tabla->coords + j] = distance (obj,tabla->piv[j]);
i++;
}
prnstats((Index)tabla);
return (Index)tabla;
}
void freeIndex (Index S, bool libobj)
{ nn *tabla = (nn*)S;
free (tabla->descr);
free (tabla->piv);
free (tabla->nums);
free (tabla);
if (libobj) closeDB();
}
void saveIndex (Index S, char *fname)
{ FILE *f = fopen(fname,"w");
nn *tabla = (nn*)S;
fwrite (tabla->descr,strlen(tabla->descr)+1,1,f);
fwrite (&tabla->n,sizeof(int),1,f);
fwrite (&tabla->coords,sizeof(int),1,f);
fwrite (tabla->nums,tabla->n * tabla->coords,sizeof(Tdist),f);
fclose (f);
}
Index loadIndex (char *fname)
{ char str[1024]; char *ptr = str;
FILE *f = fopen(fname,"r");
nn *tabla = malloc (sizeof(nn));
int i,k;
while (*ptr++ = getc(f));
tabla->descr = malloc (ptr-str);
strcpy (tabla->descr,str);
fread (&tabla->n,sizeof(int),1,f);
fread (&tabla->coords,sizeof(int),1,f);
tabla->piv = malloc (tabla->coords * sizeof(Obj));
openDB(str);
k=0; i=0;
while (k < tabla->coords)
{ tabla->piv[i] = ++k;
i++;
}
tabla->nums = malloc (tabla->n * tabla->coords * sizeof(Tdist));
fread (tabla->nums,tabla->n * tabla->coords, sizeof(Tdist),f);
fclose (f);
return (Index)tabla;
}
static Tdist DistMax (Tdist *p1, Tdist *p2, int k)
{ register int i;
Tdist max = 0,dif;
for (i=0;i max) max = dif;
}
return max;
}
static Tdist Dist1 (Tdist *p1, Tdist *p2, int k)
{ register int i;
Tdist tot = 0,dif;
for (i=0;icoords * sizeof(Tdist));
for (i=0;icoords;i++)
{ vals[i] = distance (obj,tabla->piv[i]);
if (vals[i] <= r)
{ rep++;
if (show) printobj(tabla->piv[i]);
}
}
for (;in;i++)
if (DistMax (vals,tabla->nums + tabla->coords * i,tabla->coords) <= r)
{
if (distance (obj,i+1) <= r)
{ rep++;
if (show) printobj(i+1);
}
}
free (vals);
return rep;
}
typedef struct
{ int ptr;
Tdist d1;
} Tod;
int comp (const void *a, const void *b)
{ Tod *x,*y;
x = (Tod *) a;
y = (Tod *) b;
if (x->d1 > y->d1) return 1;
if (x->d1 < y->d1) return -1;
return 0;
}
Tdist searchNN (Index S, Obj obj, int k, bool show)
{ int i;
nn *tabla = (nn*)S;
Tdist *vals = malloc (tabla->coords * sizeof(Tdist));
Tcelem res = createCelem(k);
Tdist mdif;
Tod *od = malloc (tabla->n * sizeof(Tod));
for (i=0;icoords;i++)
{ vals[i] = distance (obj,tabla->piv[i]);
addCelem (&res,tabla->piv[i],vals[i]);
}
for (i=tabla->coords;in;i++)
{ od[i-tabla->coords].ptr = i+1;
od[i-tabla->coords].d1 = Dist1(vals,tabla->nums + tabla->coords * i,
tabla->coords);
}
qsort (od,tabla->n - tabla->coords, sizeof(Tod), comp);
for (i=0;in - tabla->coords;i++)
// if (!outCelem(&res,DistMax(vals,tabla->nums + tabla->coords * od[i].ptr,
if (!outCelem(&res,DistMax(vals, tabla->nums + (tabla->coords * (od[i].ptr-1)),
tabla->coords)))
{ Tdist d;
d = distance (obj,od[i].ptr);
addCelem (&res,od[i].ptr,d);
}
free (vals); free(od);
if (show) showCelem (&res);
mdif = radCelem(&res);
freeCelem (&res);
return mdif;
}
void prnstats (Index S)
{ nn *tabla = (nn*)S;
printf ("number of elements: %i\n",tabla->n);
printf ("number of pivots: %i\n",tabla->coords);
}