/* Read and initialize global index */ int index_initialize(char *path) { FILE *fp; WINDOW *w = NULL; if (!index_initted) { w = savescr(); dialog_clear_norefresh(); have_volumes = FALSE; low_volume = high_volume = 0; /* Got any media? */ if (!mediaVerify()) { restorescr(w); return DITEM_FAILURE; } /* Does it move when you kick it? */ if (!DEVICE_INIT(mediaDevice)) { restorescr(w); return DITEM_FAILURE; } dialog_clear_norefresh(); msgNotify("Attempting to fetch %s file from selected media.", path); fp = DEVICE_GET(mediaDevice, path, TRUE); if (!fp) { msgConfirm("Unable to get packages/INDEX file from selected media.\n\n" "This may be because the packages collection is not available\n" "on the distribution media you've chosen, most likely an FTP site\n" "without the packages collection mirrored. Please verify that\n" "your media, or your path to the media, is correct and try again."); DEVICE_SHUTDOWN(mediaDevice); restorescr(w); return DITEM_FAILURE; } dialog_clear_norefresh(); msgNotify("Located INDEX, now reading package data from it..."); index_init(&Top, &Plist); if (index_read(fp, &Top)) { msgConfirm("I/O or format error on packages/INDEX file.\n" "Please verify media (or path to media) and try again."); fclose(fp); restorescr(w); return DITEM_FAILURE; } fclose(fp); index_sort(&Top); index_initted = TRUE; restorescr(w); } return DITEM_SUCCESS; }
/* Use a disgustingly simplistic bubble sort to put our lists in order */ void index_sort(PkgNodePtr top) { PkgNodePtr p, q; /* Sort everything at the top level */ for (p = top->kids; p; p = p->next) { for (q = top->kids; q; q = q->next) { if (q->next && strcmp(q->name, q->next->name) > 0) swap_nodes(q, q->next); } } /* Now sub-sort everything n levels down */ for (p = top->kids; p; p = p->next) { if (p->kids) index_sort(p); } }
static void do_search (void) { index_delete (items, 0, index_count (items)); if (! database) return; SearchState state; for (int f = 0; f < FIELDS; f ++) state.items[f] = index_new (); /* effectively limits number of search terms to 32 */ state.mask = (1 << index_count (search_terms)) - 1; g_hash_table_foreach (database, search_cb, & state); int total = 0; for (int f = 0; f < FIELDS; f ++) { int count = index_count (state.items[f]); if (count > MAX_RESULTS - total) count = MAX_RESULTS - total; if (count) { index_sort (state.items[f], item_compare); index_copy_insert (state.items[f], 0, items, -1, count); total += count; } index_free (state.items[f]); } g_array_set_size (selection, total); memset (selection->data, 0, selection->len); if (selection->len > 0) selection->data[0] = 1; }
/// column-major indices SizeVector col_major(void) const { SizeVector keys(nnz_), col_major(nnz_); for(size_t k = 0; k < nnz_; k++) { CPPAD_ASSERT_UNKNOWN( col_[k] < nc_ ); keys[k] = col_[k] * nr_ + row_[k]; } index_sort(keys, col_major); # ifndef NDEBUG for(size_t ell = 0; ell + 1 < nnz_; ell++) { size_t k = col_major[ ell ]; size_t kp = col_major[ ell + 1 ]; CPPAD_ASSERT_KNOWN( col_[k] != col_[kp] || row_[k] != row_[kp], "sparse_rc: col_major: duplicate entry in this pattern" ); CPPAD_ASSERT_UNKNOWN( col_[k]<col_[kp] || (col_[k]==col_[kp] && row_[k]<row_[kp]) ); } # endif return col_major; }
static void index_sort(mxml_index_t* ind, /* I - Index to sort */ int left, /* I - Left node in partition */ int right) { /* I - Right node in partition */ mxml_node_t* pivot, /* Pivot node */ *temp; /* Swap node */ int templ, /* Temporary left node */ tempr; /* Temporary right node */ /* * Loop until we have sorted all the way to the right... */ do { /* * Sort the pivot in the current partition... */ pivot = ind->nodes[left]; for (templ = left, tempr = right; templ < tempr;) { /* * Move left while left node <= pivot node... */ while ((templ < right) && index_compare(ind, ind->nodes[templ], pivot) <= 0) { templ ++; } /* * Move right while right node > pivot node... */ while ((tempr > left) && index_compare(ind, ind->nodes[tempr], pivot) > 0) { tempr --; } /* * Swap nodes if needed... */ if (templ < tempr) { temp = ind->nodes[templ]; ind->nodes[templ] = ind->nodes[tempr]; ind->nodes[tempr] = temp; } } /* * When we get here, the right (tempr) node is the new position for the * pivot node... */ if (index_compare(ind, pivot, ind->nodes[tempr]) > 0) { ind->nodes[left] = ind->nodes[tempr]; ind->nodes[tempr] = pivot; } /* * Recursively sort the left partition as needed... */ if (left < (tempr - 1)) { index_sort(ind, left, tempr - 1); } } while (right > (left = tempr + 1)); }
mxml_index_t* /* O - New index */ mxmlIndexNew(mxml_node_t* node, /* I - XML node tree */ const char* element, /* I - Element to index or NULL for all */ const char* attr) { /* I - Attribute to index or NULL for none */ mxml_index_t* ind; /* New index */ mxml_node_t* current, /* Current node in index */ **temp; /* Temporary node pointer array */ /* * Range check input... */ #ifdef DEBUG printf("mxmlIndexNew(node=%p, element=\"%s\", attr=\"%s\")\n", node, element ? element : "(null)", attr ? attr : "(null)"); #endif /* DEBUG */ if (!node) { return (NULL); } /* * Create a new index... */ if ((ind = calloc(1, sizeof(mxml_index_t))) == NULL) { mxml_error("Unable to allocate %d bytes for index - %s", sizeof(mxml_index_t), strerror(errno)); return (NULL); } if (attr) { ind->attr = strdup(attr); } if (!element && !attr) { current = node; } else { current = mxmlFindElement(node, node, element, attr, NULL, MXML_DESCEND); } while (current) { if (ind->num_nodes >= ind->alloc_nodes) { if (!ind->alloc_nodes) { temp = malloc(64 * sizeof(mxml_node_t*)); } else { temp = realloc(ind->nodes, (ind->alloc_nodes + 64) * sizeof(mxml_node_t*)); } if (!temp) { /* * Unable to allocate memory for the index, so abort... */ mxml_error("Unable to allocate %d bytes for index: %s", (ind->alloc_nodes + 64) * sizeof(mxml_node_t*), strerror(errno)); mxmlIndexDelete(ind); return (NULL); } ind->nodes = temp; ind->alloc_nodes += 64; } ind->nodes[ind->num_nodes ++] = current; current = mxmlFindElement(current, node, element, attr, NULL, MXML_DESCEND); } /* * Sort nodes based upon the search criteria... */ #ifdef DEBUG { int i; /* Looping var */ printf("%d node(s) in index.\n\n", ind->num_nodes); if (attr) { printf("Node Address Element %s\n", attr); puts("-------- -------- -------------- ------------------------------"); for (i = 0; i < ind->num_nodes; i ++) printf("%8d %-8p %-14.14s %s\n", i, ind->nodes[i], ind->nodes[i]->value.element.name, mxmlElementGetAttr(ind->nodes[i], attr)); } else { puts("Node Address Element"); puts("-------- -------- --------------"); for (i = 0; i < ind->num_nodes; i ++) printf("%8d %-8p %s\n", i, ind->nodes[i], ind->nodes[i]->value.element.name); } putchar('\n'); } #endif /* DEBUG */ if (ind->num_nodes > 1) { index_sort(ind, 0, ind->num_nodes - 1); } #ifdef DEBUG { int i; /* Looping var */ puts("After sorting:\n"); if (attr) { printf("Node Address Element %s\n", attr); puts("-------- -------- -------------- ------------------------------"); for (i = 0; i < ind->num_nodes; i ++) printf("%8d %-8p %-14.14s %s\n", i, ind->nodes[i], ind->nodes[i]->value.element.name, mxmlElementGetAttr(ind->nodes[i], attr)); } else { puts("Node Address Element"); puts("-------- -------- --------------"); for (i = 0; i < ind->num_nodes; i ++) printf("%8d %-8p %s\n", i, ind->nodes[i], ind->nodes[i]->value.element.name); } putchar('\n'); } #endif /* DEBUG */ /* * Return the new index... */ return (ind); }
OBJ build_bin_rel(OBJ *vals1, OBJ *vals2, uint32 size) { if (size == 0) return make_empty_rel(); // Creating the array of indexes sorted by column 1, column 2, index uint32 *index = new_uint32_array(size); index_sort(index, vals1, vals2, size); // Counting the number of unique tuples and unique values in the left column, // and releasing unnecessary objects uint32 unique_tuples = 1; uint32 prev_idx = index[0]; bool left_col_is_unique = true; for (uint32 i=1 ; i < size ; i++) { uint32 idx = index[i]; if (comp_objs(vals1[idx], vals1[prev_idx]) != 0) { // The current left column value is new, so the tuple is new too. unique_tuples++; prev_idx = idx; } else if (comp_objs(vals2[idx], vals2[prev_idx]) != 0) { // The current left column value is unchanged, but the value in the right column is new, so the tuple is new too unique_tuples++; prev_idx = idx; left_col_is_unique = false; } else { // Duplicate tuple, marking the entry as duplicate and releasing the objects index[i] = INVALID_INDEX; release(vals1[idx]); release(vals2[idx]); } } // Creating the new binary relation object BIN_REL_OBJ *rel = new_bin_rel(unique_tuples); OBJ *left_col = get_left_col_array_ptr(rel); OBJ *right_col = get_right_col_array_ptr(rel); // Copying the sorted, non-duplicate tuples into their final destination uint32 count = 0; for (uint32 i=0 ; i < size ; i++) { uint32 idx = index[i]; if (idx != INVALID_INDEX) { left_col[count] = vals1[idx]; right_col[count] = vals2[idx]; count++; } } assert(count == unique_tuples); // Creating the reverse index uint32 *rev_index = get_right_to_left_indexes(rel); stable_index_sort(rev_index, right_col, count); #ifndef NDEBUG for (uint32 i=1 ; i < count ; i++) { int cr_M = comp_objs(left_col[i-1], left_col[i]); int cr_m = comp_objs(right_col[i-1], right_col[i]); assert(cr_M > 0 | (cr_M == 0 & cr_m > 0)); } for (uint32 i=1 ; i < count ; i++) { uint32 curr_idx = rev_index[i]; uint32 prev_idx = rev_index[i-1]; int cr_M = comp_objs(right_col[prev_idx], right_col[curr_idx]); int cr_m = comp_objs(left_col[prev_idx], left_col[curr_idx]); assert(cr_M > 0 | (cr_M == 0 & cr_m > 0)); } #endif delete_uint32_array(index, size); return left_col_is_unique ? make_log_map(rel) : make_bin_rel(rel); }
size_t ADFun<Base>::SparseJacobianRev( const VectorBase& x , VectorSet& p , const VectorSize& row , const VectorSize& col , VectorBase& jac , sparse_jacobian_work& work ) { size_t i, k, ell; CppAD::vector<size_t>& order(work.order); CppAD::vector<size_t>& color(work.color); size_t m = Range(); size_t n = Domain(); // some values const Base zero(0); const Base one(1); // check VectorBase is Simple Vector class with Base type elements CheckSimpleVector<Base, VectorBase>(); CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n ); CPPAD_ASSERT_UNKNOWN (color.size() == m || color.size() == 0 ); // number of components of Jacobian that are required size_t K = size_t(jac.size()); CPPAD_ASSERT_UNKNOWN( row.size() == K ); CPPAD_ASSERT_UNKNOWN( col.size() == K ); // Point at which we are evaluating the Jacobian Forward(0, x); // check for case where nothing (except Forward above) to do if( K == 0 ) return 0; if( color.size() == 0 ) { CPPAD_ASSERT_UNKNOWN( p.n_set() == m ); CPPAD_ASSERT_UNKNOWN( p.end() == n ); // execute the coloring algorithm color.resize(m); if( work.color_method == "cppad" ) color_general_cppad(p, row, col, color); else if( work.color_method == "colpack" ) { # if CPPAD_HAS_COLPACK color_general_colpack(p, row, col, color); # else CPPAD_ASSERT_KNOWN( false, "SparseJacobianReverse: work.color_method = colpack " "and colpack_prefix missing from cmake command line." ); # endif } else CPPAD_ASSERT_KNOWN( false, "SparseJacobianReverse: work.color_method is not valid." ); // put sorting indices in color order VectorSize key(K); order.resize(K); for(k = 0; k < K; k++) key[k] = color[ row[k] ]; index_sort(key, order); } size_t n_color = 1; for(i = 0; i < m; i++) if( color[i] < m ) n_color = std::max(n_color, color[i] + 1); // weighting vector for calls to reverse VectorBase w(m); // location for return values from Reverse VectorBase dw(n); // initialize the return value for(k = 0; k < K; k++) jac[k] = zero; // loop over colors k = 0; for(ell = 0; ell < n_color; ell++) { CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell ); // combine all the rows with this color for(i = 0; i < m; i++) { w[i] = zero; if( color[i] == ell ) w[i] = one; } // call reverse mode for all these rows at once dw = Reverse(1, w); // set the corresponding components of the result while( k < K && color[ row[order[k]] ] == ell ) { jac[ order[k] ] = dw[col[order[k]]]; k++; } } return n_color; }
size_t ADFun<Base>::SparseJacobianFor( const VectorBase& x , VectorSet& p_transpose , const VectorSize& row , const VectorSize& col , VectorBase& jac , sparse_jacobian_work& work ) { size_t j, k, ell; CppAD::vector<size_t>& order(work.order); CppAD::vector<size_t>& color(work.color); size_t m = Range(); size_t n = Domain(); // some values const Base zero(0); const Base one(1); // check VectorBase is Simple Vector class with Base type elements CheckSimpleVector<Base, VectorBase>(); CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n ); CPPAD_ASSERT_UNKNOWN( color.size() == 0 || color.size() == n ); // number of components of Jacobian that are required size_t K = size_t(jac.size()); CPPAD_ASSERT_UNKNOWN( row.size() == K ); CPPAD_ASSERT_UNKNOWN( col.size() == K ); // Point at which we are evaluating the Jacobian Forward(0, x); // check for case where nothing (except Forward above) to do if( K == 0 ) return 0; if( color.size() == 0 ) { CPPAD_ASSERT_UNKNOWN( p_transpose.n_set() == n ); CPPAD_ASSERT_UNKNOWN( p_transpose.end() == m ); // execute coloring algorithm color.resize(n); if( work.color_method == "cppad" ) color_general_cppad(p_transpose, col, row, color); else if( work.color_method == "colpack" ) { # if CPPAD_HAS_COLPACK color_general_colpack(p_transpose, col, row, color); # else CPPAD_ASSERT_KNOWN( false, "SparseJacobianForward: work.color_method = colpack " "and colpack_prefix missing from cmake command line." ); # endif } else CPPAD_ASSERT_KNOWN( false, "SparseJacobianForward: work.color_method is not valid." ); // put sorting indices in color order VectorSize key(K); order.resize(K); for(k = 0; k < K; k++) key[k] = color[ col[k] ]; index_sort(key, order); } size_t n_color = 1; for(j = 0; j < n; j++) if( color[j] < n ) n_color = std::max(n_color, color[j] + 1); // initialize the return value for(k = 0; k < K; k++) jac[k] = zero; # if CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION == 1 // direction vector and return values for calls to forward VectorBase dx(n), dy(m); // loop over colors k = 0; for(ell = 0; ell < n_color; ell++) { CPPAD_ASSERT_UNKNOWN( color[ col[ order[k] ] ] == ell ); // combine all columns with this color for(j = 0; j < n; j++) { dx[j] = zero; if( color[j] == ell ) dx[j] = one; } // call forward mode for all these columns at once dy = Forward(1, dx); // set the corresponding components of the result while( k < K && color[ col[order[k]] ] == ell ) { jac[ order[k] ] = dy[row[order[k]]]; k++; } } # else // abbreviation for this value size_t max_r = CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION; CPPAD_ASSERT_UNKNOWN( max_r > 1 ); // count the number of colors done so far size_t count_color = 0; // count the sparse matrix entries done so far k = 0; while( count_color < n_color ) { // number of colors we will do this time size_t r = std::min(max_r , n_color - count_color); VectorBase dx(n * r), dy(m * r); // loop over colors we will do this tme for(ell = 0; ell < r; ell++) { // combine all columns with this color for(j = 0; j < n; j++) { dx[j * r + ell] = zero; if( color[j] == ell + count_color ) dx[j * r + ell] = one; } } size_t q = 1; dy = Forward(q, r, dx); // store results for(ell = 0; ell < r; ell++) { // set the components of the result for this color while( k < K && color[ col[order[k]] ] == ell + count_color ) { jac[ order[k] ] = dy[ row[order[k]] * r + ell ]; k++; } } count_color += r; } # endif return n_color; }