examples/ar-vineyard/ar-function-kernel.h
author Christos Mantoulidis <cmad@stanford.edu>
Tue, 28 Jul 2009 10:58:53 -0700
branchdev
changeset 153 7731c42892de
parent 74 79ee020341aa
permissions -rw-r--r--
Modified WeightedRips::generate() to incorporate the simplex-appearance-value computation (before it would have to be done explicitly by the user by a for-loop after the call to generate())

#ifndef __AR_FUNCTION_KERNEL_H__
#define __AR_FUNCTION_KERNEL_H__


#include <stack>
#include <iostream>
#include "ar-simplex3d.h"



/**
 * Represents function suitable for the FunctionKernel. Albeit very restrictive 
 * (it only supports subtraction), although that should suffice for KineticSort.
 */
class ARFunction
{
    public:
        /// Represents the three forms of the involved functions. See Appendix B of LHI paper.
        enum                        FunctionForm                                        { none, rho, lambda, phi };

    public:
                                    ARFunction(FunctionForm f, ARSimplex3D* s): 
                                        form_(f), form2_(none),
                                        simplex_(s), simplex2_(0)                       {}
                                    ARFunction(const ARFunction& other):
                                        form_(other.form_), form2_(other.form2_),
                                        simplex_(other.simplex_), 
                                        simplex2_(other.simplex2_)                      {}

        ARFunction&                 operator-=(const ARFunction& other)                 { form2_ = other.form_; simplex2_ = other.simplex_; return *this; }
        ARFunction                  operator-(const ARFunction& other)                  { return (ARFunction(*this) -= other); }

        FunctionForm                form() const                                        { return form_; }
        FunctionForm                form2() const                                       { return form2_; }
        ARSimplex3D*                simplex() const                                     { return simplex_; }
        ARSimplex3D*                simplex2() const                                    { return simplex2_; }

        std::ostream&               operator<<(std::ostream& out) const                 { return (out << "(" << form_ << ", " << simplex_ << "), (" 
                                                                                                             << form2_ << ", " << simplex2_ << ")"); }

    private:
        FunctionForm                form_, form2_;      // the function is form_ - form2_
        ARSimplex3D                 *simplex_, *simplex2_;
};

std::ostream&
operator<<(std::ostream& out, const ARFunction& f)
{ return f.operator<<(out); }

/**
 * Function kernel specialized at solving the kinds of functions involved in 
 * ARVineyard construction. We cannot use a polynomial kernel (which includes 
 * rational functions) that we already have because not all involved functions
 * are rational.
 */
class ARFunctionKernel
{
    public:
        typedef                     double                                              FieldType;
        typedef                     FieldType                                           RootType;
        typedef                     std::stack<RootType>                                RootStack;
        typedef                     ARSimplex3D::RealValue                              SimplexFieldType;

        typedef                     ARFunction                                          Function;
        typedef                     Function::FunctionForm                              FunctionForm;
    
    public:
        static void                 solve(const Function& f, RootStack& stack);
        static RootType             root(RootType r)                                    { return r; }
        static RootType             root(SimplexFieldType r)                            { return CGAL::to_double(r); }
        static int                  sign_at(const Function& f, RootType r);
        static RootType             between(RootType r1, RootType r2)                   { return (r1 + r2)/2; }
        static int                  sign_at_negative_infinity(const Function& f);

        static FieldType            value_at(const Function& f, RootType v);
};

#include "ar-function-kernel.hpp"

#endif