/** * @file gnp.h * * Abstract concepts used by THOR generalized N-body problems. * * This mostly contains blank elements that you can substitute if certain * parts of the problem don't make sense for you. */ #ifndef THOR_GNP_H #define THOR_GNP_H #include "fastlib/la/matrix.h" #include "fastlib/data/dataset.h" #include "fastlib/base/otrav.h" #include "fastlib/fx/fx.h" /** * A point in vector-space. * * This is a wrapper around Vector which implements the vec() method, because * that is what the THOR tree-builders expect. * * A side note, it's possible to have a THOR problem that doesn't use vectors * at all. Instead, define your own point, and you have to make your own * tree-builder. */ class ThorVectorPoint { private: Vector vec_; OT_DEF_BASIC(ThorVectorPoint) { OT_MY_OBJECT(vec_); } public: /** * Gets the vector. */ const Vector& vec() const { return vec_; } /** * Gets the vector. */ Vector& vec() { return vec_; } /** * Initializes a "default element" from a dataset schema. * * This is the only function that allows allocation. */ template void Init(const Param& param, const DatasetInfo& schema) { vec_.Init(schema.n_features()); vec_.SetZero(); } /** * Sets the values of this object, not allocating any memory. * * If memory needs to be allocated it must be allocated at the beginning * with Init. * * @param param ignored * @param index the index of the point, ignored * @param data the vector data read from file */ template void Set(const Param& param, index_t index, const Vector& data) { vec_.CopyValues(data); } }; struct BlankDelta { public: OT_DEF_BASIC(BlankDelta) {} public: template void Init(const Param& param) {} }; struct BlankQPostponed { public: OT_DEF_BASIC(BlankQPostponed) {} public: template void Init(const Param& param) {} template void Reset(const Param& param) {} template void ApplyPostponed(const Param& param, const BlankQPostponed& other) {} }; class BlankStat { public: OT_DEF_BASIC(BlankStat) {} public: template void Init(const Param& param) {} template void Accumulate(const Param& param, const Point& point) {} template void Accumulate(const Param& param, const BlankStat& stat, const Bound& bound, index_t n) {} template void Postprocess(const Param& param, const Bound& bound, index_t n) {} }; struct BlankQResult { public: OT_DEF_BASIC(BlankQResult) {} public: template void Init(const Param& param) {} template void Seed(const Param& param, const Point& point) {} template void Postprocess(const Param& param, const Point& q_point, index_t q_index, const RNode& r_root) {} template void ApplyPostponed(const Param& param, const QPostponed& postponed, const Point& q_point, index_t q_index) {} }; class BlankGlobalResult { public: OT_DEF_BASIC(BlankGlobalResult) {} public: template void Init(const Param& param) {} template void Accumulate(const Param& param, const BlankGlobalResult& other) {} // Delta-refinement is currently unimplemented, because we discovered it // was buggy and neglected. if this is desired, then someone may want to // reimplement it, but I'm not sure if it'd be that useful. /*template void ApplyDelta(const Param& param, const Delta& delta) {} template void UndoDelta(const Param& param, const Delta& delta) {}*/ template void Postprocess(const Param& param) {} template void Report(const Param& param, datanode *datanode) const {} template void ApplyResult(const Param& param, const QPoint& q_point, index_t q_index, const QResult& q_result) {} }; struct BlankQSummaryResult { public: OT_DEF_BASIC(BlankQSummaryResult) {} public: template void Init(const Param& param) {} template void Seed(const Param& param, const QNode& q_node) {} template void ApplyDelta(const Param& param, const Delta& delta) {} template void ApplyPostponed(const Param& param, const QPostponed& postponed, const QNode& q_node) {} template void ApplySummaryResult(const Param& param, const BlankQSummaryResult& other) {} template void StartReaccumulate(const Param& param, const QNode& q_node) {} template void Accumulate(const Param& param, const QResult& result) {} template void Accumulate(const Param& param, const BlankQSummaryResult& result, index_t n_points) {} template void FinishReaccumulate(const Param& param, const QNode& q_node) {} }; class BlankAlgorithm { public: template static bool ConsiderPairIntrinsic( const Param& param, const QNode& q_node, const RNode& r_node, const Delta& parent_delta, Delta* delta, GlobalResult* global_result, QPostponed* q_postponed) { return true; } template static bool ConsiderPairExtrinsic( const Param& param, const QNode& q_node, const RNode& r_node, const Delta& delta, const QSummaryResult& q_summary_result, const GlobalResult& global_result, QPostponed* q_postponed) { return true; } template static bool ConsiderQueryTermination( const Param& param, const QNode& q_node, const QSummaryResult& q_summary_result, const GlobalResult& global_result, QPostponed* q_postponed) { return true; } template static double Heuristic( const Param& param, const QNode& q_node, const RNode& r_node) { return 0; } }; struct DualTreeRecursionStats { public: /** * An rpc-style reductor suitable for recursion stats. */ struct Reductor { /** * Reduces two elements. * * @param right a new element to merge * @param left the element to merge into */ void Reduce(const DualTreeRecursionStats& right, DualTreeRecursionStats* left) const { left->Add(right); } }; public: double tuples_analyzed; index_t n_queries; int64 node_node_considered; int64 node_point_considered; int64 point_point_considered; OT_DEF(DualTreeRecursionStats) { OT_MY_OBJECT(tuples_analyzed); OT_MY_OBJECT(n_queries); OT_MY_OBJECT(node_node_considered); OT_MY_OBJECT(node_point_considered); OT_MY_OBJECT(point_point_considered); } public: void Init() { tuples_analyzed = 0; n_queries = 0; node_node_considered = 0; node_point_considered = 0; point_point_considered = 0; } void Add(const DualTreeRecursionStats& other) { tuples_analyzed += other.tuples_analyzed; n_queries += other.n_queries; node_node_considered += other.node_node_considered; node_point_considered += other.node_point_considered; point_point_considered += other.point_point_considered; } void Report(datanode *module) { fx_format_result(module, "p_node_node", "%g", node_node_considered / tuples_analyzed); fx_format_result(module, "p_node_point", "%g", node_point_considered / tuples_analyzed); fx_format_result(module, "p_point_point", "%g", point_point_considered / tuples_analyzed); fx_format_result(module, "r_node_node", "%g", 1.0 * node_node_considered / n_queries); fx_format_result(module, "r_node_point", "%g", 1.0 * node_point_considered / n_queries); fx_format_result(module, "r_point_point", "%g", 1.0 * point_point_considered / n_queries); } }; #endif