| 605 | } |
| 606 | |
| 607 | py::object search( |
| 608 | py::object query, |
| 609 | size_t size, // the number of resultant objects |
| 610 | float epsilon, // search parameter epsilon. the adequate range is from 0.0 to 0.05. |
| 611 | float resultExpansion, // the number of inner resultant objects |
| 612 | int edgeSize // the number of used edges for each node during the exploration of the graph. |
| 613 | ) { |
| 614 | py::array_t<float> qobject(query); |
| 615 | py::buffer_info qinfo = qobject.request(); |
| 616 | std::vector<float> qvector(static_cast<float*>(qinfo.ptr), static_cast<float*>(qinfo.ptr) + qinfo.size); |
| 617 | try { |
| 618 | NGTQG::SearchQuery sc(qvector); |
| 619 | size = size > 0 ? size : defaultNumOfSearchObjects; |
| 620 | epsilon = epsilon > -1.0 ? epsilon : defaultEpsilon; |
| 621 | resultExpansion = resultExpansion >= 0.0 ? resultExpansion : defaultResultExpansion; |
| 622 | edgeSize = edgeSize >= -2 ? edgeSize : defaultEdgeSize; |
| 623 | sc.setSize(size); // the number of resulting objects. |
| 624 | sc.setRadius(defaultRadius); // the radius of search. |
| 625 | sc.setEpsilon(epsilon); // set exploration coefficient. |
| 626 | sc.setResultExpansion(resultExpansion); // set result expansion. |
| 627 | sc.setEdgeSize(edgeSize); // if maxEdge is minus, the specified value in advance is used. |
| 628 | #ifdef NGTQG_PROBE |
| 629 | sc.setProbe(defaultProbe); |
| 630 | #endif |
| 631 | NGT::ObjectDistances objects; |
| 632 | sc.setResults(&objects); |
| 633 | NGTQG::Index::search(sc); |
| 634 | |
| 635 | numOfDistanceComputations += sc.distanceComputationCount; |
| 636 | |
| 637 | if (!withDistance) { |
| 638 | py::array_t<int> ids(objects.size()); |
| 639 | py::buffer_info idsinfo = ids.request(); |
| 640 | int *ptr = reinterpret_cast<int*>(idsinfo.ptr); |
| 641 | if (zeroNumbering) { |
| 642 | for (auto& r : objects) { |
| 643 | *ptr++ = r.id - 1; |
| 644 | } |
| 645 | } else { |
| 646 | for (auto& r : objects) { |
| 647 | *ptr++ = r.id; |
| 648 | } |
| 649 | } |
| 650 | return ids; |
| 651 | } |
| 652 | |
| 653 | py::list results; |
| 654 | if (zeroNumbering) { |
| 655 | for (auto& r : objects) { |
| 656 | results.append(py::make_tuple(r.id - 1, r.distance)); |
| 657 | } |
| 658 | } else { |
| 659 | for (auto& r : objects) { |
| 660 | results.append(py::make_tuple(r.id, r.distance)); |
| 661 | } |
| 662 | } |
| 663 | return results; |
| 664 | } catch (NGT::Exception &e) { |
nothing calls this directly
no test coverage detected