static int setup_index(struct walker *walker, struct alt_base *repo, unsigned char *sha1) { struct packed_git *new_pack; if (has_pack_file(sha1)) return 0; /* don't list this as something we can get */ if (fetch_index(walker, repo, sha1)) return -1; new_pack = parse_pack_index(sha1); new_pack->next = repo->packs; repo->packs = new_pack; return 0; }
void fetch_row(lindex li) { if (li < lp.size() && lp[li].first != sval) { return; } mwIndex gi = gmap[li]; // make sure we have enough room for this one grow_vector_to_index(lp, li, std::make_pair(sval,sval)); lindex sindex = noffset; lindex eindex = noffset; lindex deg = sr_degree(G,gi); grow_vector_to_index(lneigh, sindex+deg-1, sval); // copy everything to the local graph for (mwIndex nzi=G->ai[gi]; nzi < G->ai[gi+1]; ++nzi) { lneigh[eindex] = fetch_index(G->aj[nzi]); eindex ++; } lp[li] = std::make_pair(sindex, eindex); noffset = eindex; }
mwIndex compute(std::vector<mwIndex>& set, sparsevec& yout) { // allocate residuals for each level std::vector< std::vector< double > > resid(N); std::vector< double > y; // this is defined earlier, but outside the scope of compute(), so I redefine it here std::vector<double> psivec(N+1,0.); psivec[N] = 1; for (lindex k = 1; k <= N ; k++){ psivec[N-k] = psivec[N-k+1]*t/(double)(N-k+1) + 1; } // psivec[k] = psi_k(t) double sumresid = 0.; // the queue stores the entries for the next time step std::queue< lindex > Q; // set the initial residual, add to the queue for (size_t i=0; i<set.size(); ++i) { mwIndex ri = set[i]; lindex li = fetch_index(ri); //rij = value in entry ri of the input vector double rij = 1.; sumresid += rij*psivec[0];; grow_vector_to_index(resid[0], li, 0.); resid[0][li] += rij; Q.push( li ); } for (lindex j = 0; j < N; ++j) { // STEP 0: determine how many entries are in the queue // and determine what the residual tolerance is to // push size_t qsize = Q.size(); double pushtol = pushcoeff[j]/(double)qsize; // STEP 1: process each of the next elements in the // queue and add them to the next level for (size_t qi = 0; qi < qsize; ++qi) { lindex i = Q.front(); Q.pop(); double rij = resid[j][i]; if (rij < pushtol) { // skip to the next iteration of the loop continue; } // STEP 2: fetch the row fetch_row(i); // find the degree std::pair<lindex, lindex> offsets = lp[i]; double degofi = (double)(offsets.second - offsets.first); // update the solution grow_vector_to_index(y, i, 0.); y[i] += rij; resid[j][i] = 0.; sumresid -= rij*psivec[j];; double rijs = t*rij/(double)(j+1); double ajv = 1./degofi; double update = rijs*ajv; if (j == N-1) { // this is the terminal case, and so we add the column of A // directly to the solution vector y for (lindex nzi = offsets.first; nzi < offsets.second; ++nzi) { lindex v = lneigh[nzi]; grow_vector_to_index(y, v, 0.); y[v] += update; } npush += degofi; } else { // this is the interior case, and so we add the column of A // to the residual at the next time step. for (lindex nzi = offsets.first; nzi < offsets.second; ++nzi) { lindex v = lneigh[nzi]; grow_vector_to_index(resid[j+1], v, 0.); double reold = resid[j+1][v]; double renew = reold + update; sumresid += update*psivec[j+1];; resid[j+1][v] = renew; // For this implementation, we need all // non-zero residuals in the queue. if (reold == 0.) { Q.push( v ); } } npush += degofi; } if (maxpush > 0 && npush >= maxpush) { break; } if (sumresid < eps*exp(t)) { break; } // terminate when Q is empty, i.e. we've pushed all r(i,j) > exp(t)*eps*/(N*n*psi_j(t)) } if (sumresid < eps*exp(t)) { break; } if (maxpush > 0 && npush >= maxpush) { break; } } // end 'for' // store the output back in the solution vector y for (lindex i=0; i<y.size(); ++i) { if (y[i] > 0) { yout.map[gmap[i]] = y[i]; } } return npush; }