// file: $isip/class/pr/DecisionTreeBase/DecisionTreeBase.h // version: $Id: DecisionTreeBase.h 9448 2004-04-11 20:37:04Z gao $ // // make sure definitions are only made once: // #ifndef ISIP_DECISION_TREE_BASE #define ISIP_DECISION_TREE_BASE // isip include files // #ifndef ISIP_BI_GRAPH #include #endif #ifndef ISIP_DEBUG_LEVEL #include #endif #ifndef ISIP_FILENAME #include #endif // DecisionTreeBase: a class that defines an interface contract for all // the DecisionTrees // template class DecisionTreeBase : public BiGraph { //--------------------------------------------------------------------------- // // public constants // //--------------------------------------------------------------------------- public: // define the class name // static const String CLASS_NAME; //---------------------------------------- // // other important constants // //---------------------------------------- // define an enumeration for all possible stopping rules for splitting: // enum STOPMODE { PURE = 0, THRESH, DEPTH, DEF_STOPMODE = PURE }; // define an enumeration for run mode // enum RUNMODE { TRAIN = 0, TEST, DEF_RUNMODE = TRAIN }; // define static NameMap objects // static const NameMap STOPMODE_MAP; static const NameMap RUNMODE_MAP; //---------------------------------------- // // i/o related constants // //---------------------------------------- static const String PARAM_STOPMODE; static const String PARAM_RUNMODE; static const String PARAM_DBGL; //---------------------------------------- // // default values and arguments // //---------------------------------------- // signal processing constants // static const int32 DEF_DEPTH = 0; //---------------------------------------- // // error codes // //---------------------------------------- static const int32 ERR = 00100200; //--------------------------------------------------------------------------- // // protected data // //--------------------------------------------------------------------------- protected: // data structure declarations // typedef Pair > Attribute; typedef SingleLinkedList Attributes; // stopmode type // STOPMODE stopmode_d; // runmode type // RUNMODE runmode_d; // define parameters that are not part of the i/o for the class // int32 depth_d; // Atributes of the data // Attributes attributes_d; // debugging parameters // DebugLevel debug_level_d; //--------------------------------------------------------------------------- // // required public methods // //--------------------------------------------------------------------------- public: // method: name // static const String& name() { return CLASS_NAME; } // other static methods // diagnose method is moved outside the class header file and // defined in the DecisionTreeBaseDiagnose.h in order to avoid issues // related to preprocessing of the diagnose code. // // method: setDebug // // note that this method is not virtual since // it operates on protected data found in this class. // bool8 setDebug(Integral::DEBUG level) { debug_level_d = level; return true; } // other debug methods // virtual bool8 debug(const unichar* msg) const; // method: destructor // virtual ~DecisionTreeBase() {} // method: default constructor // DecisionTreeBase(); // method: copy constructor // DecisionTreeBase(const DecisionTreeBase& arg) { assign(arg); } // assign methods: // note that this method is not set to zero. this class must supply // a version of this method, since it manipulates protected data. // virtual bool8 assign(const DecisionTreeBase& arg); // method: sofSize // virtual int32 sofSize() const = 0; // method: read // virtual bool8 read(Sof& sof, int32 tag, const String& name) = 0; // method: write // virtual bool8 write(Sof& sof, int32 tag, const String& name) const = 0; // method: readData // virtual bool8 readData(Sof& sof, const String& pname, int32 size, bool8 param, bool8 nested) = 0; // method: writeData // virtual bool8 writeData(Sof& sof, const String& pname) const = 0; // method: eq // virtual bool8 eq(const DecisionTreeBase& arg) const; // memory management methods: // new and delete methods are omitted since only the derived // classes will be used // virtual bool8 clear(Integral::CMODE ctype = Integral::DEF_CMODE); //--------------------------------------------------------------------------- // // class-specific public methods: // set methods // // note: these functions are needed to manipulate protected data for // this class that must be invoked by the public interface for the // class. note that the set methods are virtual so a derived class // can override it if it needs to do more with the method, such as // buffer resizing. // //-------------------------------------------------------------------------- // method: setStopMode // bool8 setStopMode(STOPMODE stopmode) { stopmode_d = stopmode; return true; } // method: setRunMode // bool8 setRunMode(RUNMODE runmode) { runmode_d = runmode; return true; } // method: setDepth // bool8 setDepth(int32& depth) { depth_d = depth; return true; } //--------------------------------------------------------------------------- // // class-specific public methods: // get methods // //--------------------------------------------------------------------------- // method: getStopMode // STOPMODE getStopMode() const { return stopmode_d; } // method: getRunMode // RUNMODE getRunMode() const { return runmode_d; } // method: getDepth // int32 getDepth() { return depth_d; } // method: getLeafNodes // bool8 getLeafNodes(BiGraphVertex& node, SingleLinkedList >& leaf_nodes); // method: getAllNodes // bool8 getAllLeafNodes(BiGraphVertex& node, SingleLinkedList >& leaf_nodes); //--------------------------------------------------------------------------- // // class-specific public methods: // interface contract methods // // note: the methods below constitute the interface required by all // DecisionTrees that are going to be part of the generalized transform // software (PhoneticDecisionTree etc.). // //--------------------------------------------------------------------------- // method: runDecisionTree // virtual bool8 runDecisionTree() = 0; // method: setParser // virtual bool8 setParser(SofParser* parser) { return false; } //--------------------------------------------------------------------------- // // private methods // //--------------------------------------------------------------------------- private: }; //--------------------------------------------------------------------------- // // we define non-integral constants at the end of class definition for // templates (for non-templates these are defined in the default constructor) // //--------------------------------------------------------------------------- // constants: class name // template const String DecisionTreeBase::CLASS_NAME(L"DecisionTreeBase"); // constants: i/o related constants // template const String DecisionTreeBase::PARAM_DBGL(L"debug_level"); template const String DecisionTreeBase::PARAM_STOPMODE(L"stopmode"); template const String DecisionTreeBase::PARAM_RUNMODE(L"runmode"); // constants: name map for enum // template const NameMap DecisionTreeBase::STOPMODE_MAP(L"PURE, THRESH, DEPTH"); template const NameMap DecisionTreeBase::RUNMODE_MAP(L"TRAIN, CLASSIFY"); // below are all the methods for the DecisionTreeBase template class // // --------------------------------------------------------------------- // // required static methods // //---------------------------------------------------------------------- // --------------------------------------------------------------------- // // required debug methods // //---------------------------------------------------------------------- // method: debug // // arguments: // const unichar* msg: (input) message to print // // return: a bool8 value indicating status // template bool8 DecisionTreeBase::debug(const unichar* msg_a) const { // declare local variables // String value; String output; // output an information message // output.debugStr(name(), msg_a, L":"); Console::put(output); Console::increaseIndention(); // display debug level // output.debugStr(name(), msg_a, L"debug_level_d", debug_level_d.getName()); Console::put(output); // display the various modes // output.debugStr(name(), msg_a, L"stopmode_d", STOPMODE_MAP.getName((int32)stopmode_d)); Console::put(output); output.debugStr(name(), msg_a, L"runmode_d", RUNMODE_MAP.getName((int32)runmode_d)); Console::put(output); // display common decision tree parameters // value.assign(depth_d); output.debugStr(name(), msg_a, L"depth_d", value); Console::put(output); // display the attributes // attributes_d.debug(L"attributes_d"); // call the parent BiGraph debug method to debug the tree // BiGraph::debug(L"BiGraph Tree"); // decrease indention // Console::decreaseIndention(); // exit gracefully // return true; } //------------------------------------------------------------------------ // // required destructor/constructor(s) // //----------------------------------------------------------------------- // method: constructor // // arguments: none // // return: none // // this is the default constructor // template DecisionTreeBase::DecisionTreeBase() { // initialize protected data // stopmode_d = DEF_STOPMODE; runmode_d = DEF_RUNMODE; depth_d = DEF_DEPTH; } //------------------------------------------------------------------------- // // required assign methods // //------------------------------------------------------------------------- // method: assign // // arguments: // const DecisionTreeBase& arg: (input) object to assign // // return: a bool8 value indicating status // // this method assigns the input argument to "this". // template bool8 DecisionTreeBase::assign(const DecisionTreeBase& arg_a) { // assign data related to i/o // debug_level_d = arg_a.debug_level_d; // assign other protected data // stopmode_d = arg_a.stopmode_d; runmode_d = arg_a.runmode_d; depth_d = arg_a.depth_d; attributes_d = arg_a.attributes_d; // exit gracefully // return true; } // method: eq // // arguments: // const DecisionTreeBase& arg: (input) input object // // return: a bool8 value indicating status // // this method checks if two objects are the same // template bool8 DecisionTreeBase::eq(const DecisionTreeBase& arg_a) const { // check all internal data // if (((DebugLevel)debug_level_d != arg_a.debug_level_d) || (stopmode_d != arg_a.stopmode_d) || (runmode_d != arg_a.runmode_d) || (depth_d != arg_a.depth_d) || (!attributes_d.eq(arg_a.attributes_d)) || !(((BiGraph*)this)->eq((BiGraph)arg_a))) { return false; } // exit gracefully // return true; } // method: clear // // arguments: // Integral::CMODE ctype: (input) clear mode // // return: a bool8 value indicating status // template bool8 DecisionTreeBase::clear(Integral::CMODE ctype_a) { // debug level is typically a parameter, so keep its setting in // retain mode. // if (ctype_a != Integral::RETAIN) { debug_level_d.assign(Integral::DEF_DEBUG); } // reset to initial state for all values of ctype_a // stopmode_d = DEF_STOPMODE; runmode_d = DEF_RUNMODE; // clear the attributes // attributes_d.clear(ctype_a); // call the clear method of the Bigraph // clear(ctype_a); // exit gracefully // return true; } // method: getLeafNodes // // arguments: // BiGraphVertex& node: (input) input node // SingleLinkedList >& leaf_nodes: (output) list of // output nodes // // return: a bool8 value indicating status // // this method returns the LeafNodes at same-level or one-level below // a node in the decisiontree // template bool8 DecisionTreeBase::getLeafNodes(BiGraphVertex& node_a, SingleLinkedList >& leaf_nodes_a) { // local variables // DoubleLinkedList< BiGraphArc >* children; BiGraphArc* child; BiGraphVertex* child_node; BiGraphVertex* temp_node; SingleLinkedList< BiGraphVertex > nodes(DstrBase::USER); SingleLinkedList > nonleaf_nodes(DstrBase::USER); bool8 nonleaf = true; // get all the child nodes of this node // children = node_a.getChildren(); // if this node has child nodes, accumulate the child nodes // if (node_a.gotoFirstChild()) { // loop-over all the child nodes and accumulate these nodes // for (bool8 more = children->gotoFirst(); more; more = children->gotoNext()) { child = children->getCurr(); child_node = child->getVertex(); nodes.insert(child_node); } } // else this node is a leaf node, no child nodes and so exit // else { leaf_nodes_a.insert(&node_a); nonleaf = false; } // loop till all the leafnodes are found // while (nonleaf) { nonleaf = false; // loop over all the nodes and accumulate the leaf nodes // for (bool8 more = nodes.gotoFirst(); more; more = nodes.gotoNext()) { temp_node = nodes.getCurr(); // nodes that don't have children are leaf nodes // if (!temp_node->gotoFirstChild()) { // add this leaf node to the singlelinkedlist // leaf_nodes_a.insert(temp_node); } // store the nonleaf nodes seperately // else { nonleaf_nodes.insert(temp_node); nonleaf = true; } } // reset the memory // nodes.clear(Integral::RESET); // loop over all the nonleaf nodes and accumulate their children // for (bool8 more = nonleaf_nodes.gotoFirst(); more; more = nonleaf_nodes.gotoNext()) { // get all the child nodes of this nodes // temp_node = nonleaf_nodes.getCurr(); children = temp_node->getChildren(); // loop-over all the child nodes and accumulate them // for (bool8 morea = children->gotoFirst(); morea; morea = children->gotoNext()) { child = children->getCurr(); child_node = child->getVertex(); nodes.insert(child_node); } } // reset the memory // nonleaf_nodes.clear(Integral::RESET); } // exit gracefully // return true; } // method: getAllLeafNodes // // arguments: // BiGraphVertex& node: (input) input node // SingleLinkedList >& leaf_nodes: (output) list of // output nodes // // return: a bool8 value indicating status // // this method returns all the LeafNodes below a specified node in the // decisiontree // template bool8 DecisionTreeBase::getAllLeafNodes(BiGraphVertex& node_a, SingleLinkedList >& leaf_nodes_a) { // local variables // DoubleLinkedList< BiGraphArc >* children; BiGraphArc* child; BiGraphVertex* child_node; SingleLinkedList< BiGraphVertex > nodes(DstrBase::USER); SingleLinkedList > nonleaf_nodes(DstrBase::USER); // get all the child nodes of this node // children = node_a.getChildren(); // if this node has child nodes, accumulate the child nodes // if (node_a.gotoFirstChild()) { // loop-over all the child nodes and accumulate these nodes // for (bool8 more = children->gotoFirst(); more; more = children->gotoNext()) { child = children->getCurr(); child_node = child->getVertex(); getAllLeafNodes(*child_node, leaf_nodes_a); } } // else this node is a leaf node, no child nodes and so exit // else { leaf_nodes_a.insert(&node_a); } // exit gracefully // return true; } // end of include file // #endif