float * lasvm_kcache_query_row(lasvm_kcache_t *self, int i, int len) { ASSERT(i>=0); if (i<self->l && len<=self->rsize[i]) { self->rnext[self->rprev[i]] = self->rnext[i]; self->rprev[self->rnext[i]] = self->rprev[i]; } else { int olen, p, q; float *d; if (i >= self->l || len >= self->l) xminsize(self, max(1+i,len)); olen = self->rsize[i]; if (olen < 0) { self->rdiag[i] = (*self->func)(i, i, self->closure); olen = self->rsize[i] = 0; } xextend(self, i, len); q = self->i2r[i]; d = self->rdata[i]; for (p=olen; p<len; p++) { int j = self->r2i[p]; if (i == j) d[p] = self->rdiag[i]; else if (q < self->rsize[j]) d[p] = self->rdata[j][q]; else d[p] = (*self->func)(i, j, self->closure); } self->rnext[self->rprev[i]] = self->rnext[i]; self->rprev[self->rnext[i]] = self->rprev[i]; xpurge(self); } self->rprev[i] = -1; self->rnext[i] = self->rnext[-1]; self->rnext[self->rprev[i]] = i; self->rprev[self->rnext[i]] = i; return self->rdata[i]; }
void lasvm_kcache_swap_ri(lasvm_kcache_t *self, int r1, int i2) { xminsize(self, 1+max(r1,i2)); xswap(self, self->r2i[r1], i2, r1, self->i2r[i2]); }
void lasvm_kcache_swap_ii(lasvm_kcache_t *self, int i1, int i2) { xminsize(self, 1+max(i1,i2)); xswap(self, i1, i2, self->i2r[i1], self->i2r[i2]); }
void lasvm_kcache_swap_rr(lasvm_kcache_t *self, int r1, int r2) { xminsize(self, 1+max(r1,r2)); xswap(self, self->r2i[r1], self->r2i[r2], r1, r2); }
int * lasvm_kcache_r2i(lasvm_kcache_t *self, int n) { xminsize(self, n); return self->r2i; }
int * lasvm_kcache_i2r(lasvm_kcache_t *self, int n) { xminsize(self, n); return self->i2r; }
int lasvm_kcache_shuffle(lasvm_kcache_t *self, int *ilist, int ilen) { int k = 0; int maxid = 0; float *m = 0; char *c = 0; int mrl = 0; int i, j, r; ASSERT(ilist); ASSERT(ilen>0); /* find max index */ for (r=0; r<ilen; r++) { i = ilist[r]; ASSERT(i>=0 && i<self->l); maxid = max(maxid, i); } /* compute map */ xminsize(self, maxid+1); c = xmalloc(self->l); memset(c, 0, self->l * sizeof(char)); for (r=0; r<ilen; r++) c[ ilist[r] ] = 1; /* sort ilist and remove duplicates */ ilen = 0; for (i=0; i<self->l; i++) if (c[i]) ilist[ilen++] = i; /* reorganize cache entries */ m = xmalloc(ilen * sizeof(float)); k = self->rnext[-1]; while (k >= 0) { int nk = self->rnext[k]; int n = self->rsize[k]; int rr = self->i2r[k]; float *d = self->rdata[k]; /* collect */ for (j=0; j<ilen; j++) { int r = self->i2r[ ilist[j] ]; if (r < n) m[j] = d[r]; else if (r == rr) m[j] = self->rdiag[r]; else break; } /* copy */ if (j < n) xtruncate(self, k, j); else xextend(self, k, j); d = self->rdata[k]; for (i=0; i<j; i++) d[i] = m[i]; mrl = max(mrl, j); /* next */ k = nk; } free(m); /* recompose i2r and r2i */ r = 0; for (i=0; i<self->l; i++) if (c[i]) self->r2i[r++] = i; for (i=0; i<self->l; i++) if (!c[i]) self->r2i[r++] = i; ASSERT(r == self->l); for (r=0; r<self->l; r++) self->i2r[ self->r2i[r] ] = r; ASSERT(mrl <= ilen); free(c); /* return */ self->maxrowlen = mrl; return ilen; }