//============================================================================== double LRBSpline2D::evalBasisFunc(double u, double v) const //============================================================================== { bool u_on_end = (u == umax()); bool v_on_end = (v == vmax()); return B(degree(XFIXED), u, &kvec(XFIXED)[0], mesh_->knotsBegin(XFIXED), u_on_end)* B(degree(YFIXED), v, &kvec(YFIXED)[0], mesh_->knotsBegin(YFIXED), v_on_end); }
//============================================================================== double LRBSpline2D::evalBasisFunction(double u, double v, int u_deriv, int v_deriv, bool u_at_end, bool v_at_end) const //============================================================================== { return compute_univariate_spline(degree(XFIXED), u, kvec(XFIXED), mesh_->knotsBegin(XFIXED), u_deriv, u_at_end) * compute_univariate_spline(degree(YFIXED), v, kvec(YFIXED), mesh_->knotsBegin(YFIXED), v_deriv, v_at_end); }
//============================================================================== double LRBSpline2D::getGrevilleParameter(Direction2D d) const { int nmb = (d == XFIXED) ? (int)kvec_u_.size() - 1 : (int)kvec_v_.size() - 1; int ki; double par = 0; for (ki=1; ki<nmb; ++ki) par += mesh_->kval(d, kvec(d)[ki]); par /= (double)(nmb-1); return par; }
//============================================================================== void LRBSpline2D::evalBasisLineDer(int nmb_der, Direction2D d, const vector<double>& parval, vector<double>& derivs) const //============================================================================== { if (nmb_der == 0) return; // No derivatives to compute nmb_der = std::max(nmb_der, 3); // At most third order derivatives // Allocate stratch int nmb = (int)(parval.size()); derivs.resize(nmb_der*nmb); vector<double> ebder((nmb_der+1)*nmb); // Compute derivatives of univariate basis int ki; for (ki=0; ki<nmb; ++ki) { // For the time being. Should be made more effective for (int kii=0; kii<=nmb_der; ++kii) { ebder[ki*(nmb_der+1)+kii] = compute_univariate_spline(degree(d), parval[ki], kvec(d), mesh_->knotsBegin(d), kii, false); } } // Multiply with weight // NOTE that rational functions are NOT handled int kr; for (ki=0; ki<nmb; ++ki) { derivs[ki] = gamma_*ebder[ki*nmb_der+1]; // dt if (nmb_der > 1) { derivs[nmb+ki] = gamma_*ebder[ki*nmb_der+2]; // dtt if (nmb_der > 2) { derivs[2*nmb+ki] = gamma_*ebder[ki*nmb_der+3]; // dttt } } } }
void levelledDatabaseTest() { ups_parameter_t env_params[] = { { UPS_PARAM_PAGESIZE, 1024 }, { 0, 0 } }; ups_parameter_t db_params[] = { { UPS_PARAM_KEYSIZE, 80 }, { 0, 0 } }; close(); require_create(0, env_params, 0, db_params); DbProxy dbp(db); std::vector<uint8_t> kvec(80); std::vector<uint8_t> rvec; for (int i = 0; i < 100; i++) { *(int *)&kvec[0] = i; dbp.require_insert(kvec, rvec) .require_check_integrity(); } }
w_rc_t ShoreTPCCEnv::_post_init_impl() { #ifndef CFG_HACK return (RCOK); #endif TRACE (TRACE_ALWAYS, "Padding WAREHOUSES"); ss_m* db = this->db(); // lock the WH table warehouse_t* wh = warehouse_desc(); index_desc_t* idx = wh->indexes(); int icount = wh->index_count(); stid_t wh_fid = wh->fid(); // lock the table and index(es) for exclusive access W_DO(db->lock(wh_fid, EX)); for(int i=0; i < icount; i++) { for(int j=0; j < idx[i].get_partition_count(); j++) W_DO(db->lock(idx[i].fid(j), EX)); } guard<ats_char_t> pts = new ats_char_t(wh->maxsize()); /* copy and pad all tuples smaller than 4k WARNING: this code assumes that existing tuples are packed densly so that all padded tuples are added after the last unpadded one */ bool eof; static int const PADDED_SIZE = 4096; // we know you can't fit two 4k records on a single page array_guard_t<char> padding = new char[PADDED_SIZE]; std::vector<rid_t> hit_list; { guard<warehouse_man_impl::table_iter> iter; { warehouse_man_impl::table_iter* tmp; W_DO(warehouse_man()->get_iter_for_file_scan(db, tmp)); iter = tmp; } int count = 0; table_row_t row(wh); rep_row_t arep(pts); int psize = wh->maxsize()+1; W_DO(iter->next(db, eof, row)); while (1) { pin_i* handle = iter->cursor(); if (!handle) { TRACE(TRACE_ALWAYS, " -> Reached EOF. Search complete (%d)\n", count); break; } // figure out how big the old record is int hsize = handle->hdr_size(); int bsize = handle->body_size(); if (bsize == psize) { TRACE(TRACE_ALWAYS, " -> Found padded WH record. Stopping search (%d)\n", count); break; } else if (bsize > psize) { // too big... shrink it down to save on logging handle->truncate_rec(bsize - psize); fprintf(stderr, "+"); } else { // copy and pad the record (and mark the old one for deletion) rid_t new_rid; vec_t hvec(handle->hdr(), hsize); vec_t dvec(handle->body(), bsize); vec_t pvec(padding, PADDED_SIZE-bsize); W_DO(db->create_rec(wh_fid, hvec, PADDED_SIZE, dvec, new_rid)); W_DO(db->append_rec(new_rid, pvec)); // for small databases, first padded record fits on this page if (not handle->up_to_date()) handle->repin(); // mark the old record for deletion hit_list.push_back(handle->rid()); // update the index(es) vec_t rvec(&row._rid, sizeof(rid_t)); vec_t nrvec(&new_rid, sizeof(new_rid)); for(int i=0; i < icount; i++) { int key_sz = warehouse_man()->format_key(idx+i, &row, arep); vec_t kvec(arep._dest, key_sz); /* destroy the old mapping and replace it with the new one. If it turns out this is super-slow, we can look into probing the index with a cursor and updating it directly. */ int pnum = _pwarehouse_man->get_pnum(&idx[i], &row); stid_t fid = idx[i].fid(pnum); if(idx[i].is_mr()) { W_DO(db->destroy_mr_assoc(fid, kvec, rvec)); // now put the entry back with the new rid el_filler ef; ef._el.put(nrvec); W_DO(db->create_mr_assoc(fid, kvec, ef)); } else { W_DO(db->destroy_assoc(fid, kvec, rvec)); // now put the entry back with the new rid W_DO(db->create_assoc(fid, kvec, nrvec)); } } fprintf(stderr, "."); } // next! count++; W_DO(iter->next(db, eof, row)); } fprintf(stderr, "\n"); // put the iter out of scope } // delete the old records int hlsize = hit_list.size(); TRACE(TRACE_ALWAYS, "-> Deleting (%d) old unpadded records\n", hlsize); for(int i=0; i < hlsize; i++) { W_DO(db->destroy_rec(hit_list[i])); } return (RCOK); }
w_rc_t ShoreTPCBEnv::_pad_BRANCHES() { ss_m* db = this->db(); // lock the BRANCHES table branch_t* br = branch_man->table(); std::vector<index_desc_t*>& br_idx = br->get_indexes(); // lock the table and index(es) for exclusive access W_DO(ss_m::lm->intent_vol_lock(br->primary_idx()->stid().vol, okvl_mode::IX)); W_DO(ss_m::lm->intent_store_lock(br->primary_idx()->stid(), okvl_mode::X)); for(size_t i=0; i < br_idx.size(); i++) { W_DO(ss_m::lm->intent_store_lock(br_idx[i]->stid(), okvl_mode::X)); } guard<ats_char_t> pts = new ats_char_t(br->maxsize()); // copy and pad all tuples smaller than 4k // WARNING: this code assumes that existing tuples are packed // densly so that all padded tuples are added after the last // unpadded one bool eof; // we know you can't fit two 4k records on a single page static int const PADDED_SIZE = 4096; array_guard_t<char> padding = new char[PADDED_SIZE]; std::vector<rid_t> hit_list; { table_scan_iter_impl<branch_t>* iter = new table_scan_iter_impl<branch_t>(branch_man->table()); int count = 0; table_row_t row(br); rep_row_t arep(pts); int psize = br->maxsize()+1; W_DO(iter->next(db, eof, row)); while (!eof) { // figure out how big the old record is int bsize = row.size(); if (bsize == psize) { TRACE(TRACE_ALWAYS, "-> Found padded BRANCH record. Stopping search (%d)\n", count); break; } else if (bsize > psize) { // too big... shrink it down to save on logging // handle->truncate_rec(bsize - psize); fprintf(stderr, "+"); // CS: no more pin_i -> do nothing } else { // copy and pad the record (and mark the old one for deletion) rid_t new_rid; vec_t hvec(handle->hdr(), hsize); vec_t dvec(handle->body(), bsize); vec_t pvec(padding, PADDED_SIZE-bsize); W_DO(db->create_rec(br_fid, hvec, PADDED_SIZE, dvec, new_rid)); W_DO(db->append_rec(new_rid, pvec)); // mark the old record for deletion hit_list.push_back(handle->rid()); // update the index(es) vec_t rvec(&row._rid, sizeof(rid_t)); vec_t nrvec(&new_rid, sizeof(new_rid)); for(int i=0; i < br_idx_count; i++) { int key_sz = branch_man()->format_key(br_idx+i, &row, arep); vec_t kvec(arep._dest, key_sz); // destroy the old mapping and replace it with the new // one. If it turns out this is super-slow, we can // look into probing the index with a cursor and // updating it directly. int pnum = _pbranch_man->get_pnum(&br_idx[i], &row); stid_t fid = br_idx[i].fid(pnum); W_DO(db->destroy_assoc(fid, kvec, rvec)); // now put the entry back with the new rid W_DO(db->create_assoc(fid, kvec, nrvec)); } fprintf(stderr, "."); } // next! count++; W_DO(iter->next(db, eof, row)); } TRACE(TRACE_ALWAYS, "padded records added\n"); delete iter; } // delete the old records int hlsize = hit_list.size(); TRACE(TRACE_ALWAYS, "-> Deleting (%d) old BRANCH unpadded records\n", hlsize); for(int i=0; i < hlsize; i++) { W_DO(db->destroy_rec(hit_list[i])); } return (RCOK); }
//============================================================================== vector<double> LRBSpline2D::unitIntervalBernsteinBasis(double start, double stop, Direction2D d) const //============================================================================== { // Get knot vector, where the knots are translated by start -> 0.0 and stop -> 1.0 vector<double> knots; vector<int> knots_int = kvec(d); double slope = 1.0/(stop - start); int deg = degree(d); for (int i = 0; i < deg + 2; ++i) knots.push_back(slope * (mesh_->kval(d,knots_int[i]) - start)); // Get the position of the interval containing [0,1]. We assume that for // some k, knots[k] <= 0.0 and knots[k+1] >= 1.0, and let interval_pos be this k. // We use 0.5 instead of 1.0 to break the loop, in order to avoid using tolerances. // Any number in the open interval (0,1) would work. int interval_pos; for (interval_pos = 0; interval_pos <= deg; ++interval_pos) if (knots[interval_pos + 1] >= 0.5) break; // Prepare array holding the Bernstein basis coefficients. // After each step for each polynomial degree (value of k in outermost loop below), // the polynomial part on the interval [ knots[interval_pos], knots[interval_pos+1] ]) // of the k-degree B-spline defined by knot vector knot[i],...,knot[i+k+1] is given // by coefficients coefs[i][0],...,coefs[i][k]. At the end, the coefficients to be // returned are in coefs[0] vector<vector<double> > coefs(deg+1); for (int i = 0; i <= deg; ++i) coefs[i].resize(deg + 1 - i); coefs[interval_pos][0] = 1.0; for (int k = 1; k <=deg; ++k) for (int i = 0; i <= deg - k; ++i) if (i >= interval_pos - k && i <= interval_pos) // Only look at B-splines with support in interval { double coefs_i_jmin1 = 0.0; // For caching coefs[i][j-1] in inner loop // Store 1/(k*(knots[i+k]-knots[i])) and same for next interval. The denominator should not be zero // (because knots[interval_pos] < knots[interval_pos +1]) but just in case we use the standard // assumption 1/0 = 0 from spline arithmetics double denom_0 = (double)k*(knots[i + k] - knots[i]); if (denom_0 != 0.0) denom_0 = 1.0/denom_0; double denom_1 = (double)k*(knots[i + k + 1] - knots[i + 1]); if (denom_1 != 0.0) denom_1 = 1.0/denom_1; // Some factors used several times double f0 = (1.0 - knots[i]) * denom_0; double f1 = (knots[i + k + 1] - 1.0) * denom_1; double f2 = f0 - denom_0; double f3 = f1 + denom_1; // Calculate the new coefficients for (int j = 0; j <= k; ++j) { double res = 0.0; if (j > 0) res += (f0 * coefs_i_jmin1 + f1 * coefs[i + 1][j - 1]) * (double)j; if (j < k) res += (f2 * coefs[i][j] + f3 * coefs[i + 1][j]) * (double)(k - j); coefs_i_jmin1 = coefs[i][j]; coefs[i][j] = res; } } return coefs[0]; }
//============================================================================== void LRBSpline2D::evalBasisGridDer(int nmb_der, const vector<double>& par1, const vector<double>& par2, vector<double>& derivs) const //============================================================================== { if (nmb_der == 0) return; // No derivatives to compute nmb_der = std::max(nmb_der, 3); // At most third order derivatives // Allocate stratch int nmb1 = (int)(par1.size()); int nmb2 = (int)(par2.size()); int nmb_part_der = 2; if (nmb_der > 1) nmb_part_der += 3; if (nmb_der > 2) nmb_part_der += 4; derivs.resize(nmb_part_der*nmb1*nmb2); vector<double> ebder1((nmb_der+1)*nmb1); vector<double> ebder2((nmb_der+1)*nmb2); // Compute derivatives of univariate basis int ki, kj; for (ki=0; ki<nmb1; ++ki) { // For the time being. Should be made more effective for (int kii=0; kii<=nmb_der; ++kii) { ebder1[ki*(nmb_der+1)+kii] = compute_univariate_spline(degree(XFIXED), par1[ki], kvec(XFIXED), mesh_->knotsBegin(XFIXED), kii, false); } } for (ki=0; ki<nmb2; ++ki) { // For the time being. Should be made more effective for (int kii=0; kii<=nmb_der; ++kii) { ebder2[ki*(nmb_der+1)+kii] = compute_univariate_spline(degree(YFIXED), par2[ki], kvec(YFIXED), mesh_->knotsBegin(YFIXED), kii, false); } } // Combine univariate results // NOTE that rational functions are NOT handled int kr; for (kj=0; kj<nmb2; ++kj) for (ki=0; ki<nmb1; ++ki) { derivs[kj*nmb1+ki] = gamma_*ebder1[ki*nmb_der+1]*ebder2[kj*nmb_der]; // du derivs[(nmb2+kj)*nmb1+ki] = gamma_*ebder1[ki*nmb_der]*ebder2[kj*nmb_der+1]; // dv if (nmb_der > 1) { derivs[(2*nmb2+kj)*nmb1+ki] = gamma_*ebder1[ki*nmb_der+2]*ebder2[kj*nmb_der]; // duu derivs[(3*nmb2+kj)*nmb1+ki] = gamma_*ebder1[ki*nmb_der+1]*ebder2[kj*nmb_der+1]; // duv derivs[(4*nmb2+kj)*nmb1+ki] = gamma_*ebder1[ki*nmb_der]*ebder2[kj*nmb_der+2]; // dvv if (nmb_der > 2) { derivs[(5*nmb2+kj)*nmb1+ki] = gamma_*ebder1[ki*nmb_der+3]*ebder2[kj*nmb_der]; // duuu derivs[(6*nmb2+kj)*nmb1+ki] = gamma_*ebder1[ki*nmb_der+2]*ebder2[kj*nmb_der+1]; // duuv derivs[(7*nmb2+kj)*nmb1+ki] = gamma_*ebder1[ki*nmb_der+1]*ebder2[kj*nmb_der+2]; // duvv derivs[(8*nmb2+kj)*nmb1+ki] = gamma_*ebder1[ki*nmb_der]*ebder2[kj*nmb_der+3]; // dvvv } } } }