vec CoSaMP(const mat & Phi, const vec & u, int K, int max_iter, double tol1, int D){ assert(K<= 2*D); assert(K>=1); assert(Phi.rows() == Phi.cols()); assert(Phi.rows() == D); assert(u.size() == D); vec Sest = zeros(D); vec utrue = Sest; vec v = u; int t=1; ivec T2; while (t<max_iter){ ivec z = sort_index(fabs(Phi.transpose() * v)); z = reverse(z); ivec Omega = head(z,2*K); ivec T=sort_union(Omega,T2); mat phit=get_cols(Phi, T); vec b; bool ret = backslash(phit, u, b); assert(ret); ret = false;//avoid warning b= fabs(b); ivec z3 = sort_index(b); z3 = reverse(z3); Sest=zeros(D); for (int i=0; i< K; i++) set_val(Sest, z3[i], b[z3[i]]); ivec z2 = sort_index(fabs(Sest)); z2 = reverse(z2); T2 = head(z2,K-1); v=u-Phi*Sest; double n2 = max(fabs(v)); if (n2 < tol1) break; t++; } return Sest; }
RelationSpec* sortmerge_join(RelationSpec* rSpec, RelationSpec* sSpec, const string &mainJoinAttr, const vector<string> &joinAttrOrder, size_t& recordCount, bool saveResult, bool printProcess) { // sort relations based on join attributes int roffset = rSpec->get_attr_idx(mainJoinAttr); int soffset = sSpec->get_attr_idx(mainJoinAttr); assert(roffset != -1); assert(soffset != -1); sort(rSpec->memDB.begin(), rSpec->memDB.end(), sorter(roffset)); sort(sSpec->memDB.begin(), sSpec->memDB.end(), sorter(soffset)); // Check whether there are other attributes (beside the mainJoinAttr) need to be joined at the same time vector<string> commonAttrs = sort_intersect(rSpec->attrNames, sSpec->attrNames); assert(commonAttrs.size() > 0); vector<string> otherAttrsToJoin; if (commonAttrs.size() == 1) { assert(commonAttrs.at(0) == mainJoinAttr); } else { // cerr << "Additional attributes: "; // make sure the mainJoinAttr is in the commonAttrs int mainIdx = find_offset(commonAttrs, mainJoinAttr); assert(mainIdx != -1); // get other attributes need to be joined for (int i = 0; i != commonAttrs.size(); i++) { string curCommonAttr = commonAttrs.at(i); if (i == mainIdx) continue; if (find_offset(joinAttrOrder, curCommonAttr) != -1) { // cerr << curCommonAttr << " "; otherAttrsToJoin.push_back(curCommonAttr); } } // cerr << ". "; } int otherSize = otherAttrsToJoin.size(); int *rOffs = new int[otherSize]; int *sOffs = new int[otherSize]; for (int i = 0; i != otherAttrsToJoin.size(); i++) { string curAttr = otherAttrsToJoin.at(i); rOffs[i] = rSpec->get_attr_idx(curAttr); sOffs[i] = sSpec->get_attr_idx(curAttr); } // Create the joint relation specification file // The attributes of the joined relation is a distinct union of the attributes of the two input relations vector<string> nAttrNames = sort_union(rSpec->attrNames, sSpec->attrNames); int nAttrSize = nAttrNames.size(); string nRelName = rSpec->relName + sSpec->relName; RelationSpec* nSpec = new RelationSpec(nRelName, "", nAttrNames, false); int* rAttrIdx = new int[nAttrSize]; int* sAttrIdx = new int[nAttrSize]; for (int i = 0; i != nAttrSize; i++) { string curAttr = nAttrNames.at(i); rAttrIdx[i] = find_offset(rSpec->attrNames, curAttr); sAttrIdx[i] = find_offset(sSpec->attrNames, curAttr); } // cerr << "Joined schema: "; // for (int i = 0; i != nAttrNames.size(); i++) // cerr << nAttrNames.at(i) << " "; // cerr << endl; // Here start the core part of the sort merge join algorithm bool firstRun = true; int rKey, sKey, rLastKey = -1, sLastIdx = 0; size_t rSize = rSpec->memDB.size(); size_t sSize = sSpec->memDB.size(); size_t rIdx = -1, sIdx = -1; int *rRecPtr, *sRecPtr, *nRecPtr; for (rIdx = 0; rIdx != rSize; rIdx++) { rRecPtr = rSpec->memDB[rIdx]; rKey = *(rRecPtr + roffset); if (!firstRun && rKey != rLastKey) { sLastIdx = sIdx; } for (sIdx = sLastIdx; sIdx != sSize; sIdx++) { sRecPtr = sSpec->memDB[sIdx]; sKey = *(sRecPtr + soffset); if (rKey == sKey) { // Before we move on, we need to check other common attributes are the same, too. if (!check_other_attrs(rRecPtr, sRecPtr, rOffs, sOffs, otherSize)) { continue; } else { // Making new records. recordCount++; if (saveResult) { nRecPtr = new int[nAttrSize]; make_record(rRecPtr, sRecPtr, rAttrIdx, sAttrIdx, nAttrSize, nRecPtr); nSpec->memDB.push_back(nRecPtr); } if (printProcess) { if (recordCount % PRINT_NUM == 1) cerr << "."; if (recordCount % (PRINT_NUM * 20) == 1) cerr << endl; } } } else { if (rKey > sKey) { continue; } else { // rKey < sKey break; } } } rLastKey = rKey; firstRun = false; } // cerr << endl; // cerr << "Joining done. Records: " << recordCount << endl; //clean up delete[] rOffs; delete[] sOffs; delete[] rAttrIdx; delete[] sAttrIdx; return nSpec; }