whitespace cleanup: replace tabs and remove trailing whitespace
This commit is contained in:
@ -80,7 +80,7 @@ const Complex cerfc_continued_fraction( const Complex z )
|
||||
C = z + a/C ;
|
||||
|
||||
if (D.real() == 0.0 && D.imag() == 0.0)
|
||||
D = tiny ;
|
||||
D = tiny ;
|
||||
|
||||
D = 1.0 / D ;
|
||||
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
*
|
||||
* Copyright (c), Ilya Valuev 2006 All Rights Reserved.
|
||||
*
|
||||
* Author : Ilya Valuev, MIPT, Moscow, Russia
|
||||
* Author : Ilya Valuev, MIPT, Moscow, Russia
|
||||
*
|
||||
* Project : ivutils
|
||||
* Project : ivutils
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*s****************************************************************************
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
*
|
||||
* Copyright (c), Ilya Valuev 2005 All Rights Reserved.
|
||||
*
|
||||
* Author : Ilya Valuev, MIPT, Moscow, Russia
|
||||
* Author : Ilya Valuev, MIPT, Moscow, Russia
|
||||
*
|
||||
* Project : GridMD, ivutils
|
||||
* Project : GridMD, ivutils
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ void ArithmeticPathBase<element_type, scalar_type, path_type>::computeValue() {
|
||||
exponent_tmp += weights[j_elem] * frame_element_distances[i_frame][j_elem] * weights[j_elem] * frame_element_distances[i_frame][j_elem];
|
||||
}
|
||||
exponent_tmp = exponent_tmp * -1.0 * lambda;
|
||||
// prevent underflow if the argument of cvm::exp is less than -708.4
|
||||
// prevent underflow if the argument of cvm::exp is less than -708.4
|
||||
if (exponent_tmp > -708.4) {
|
||||
exponent_tmp = cvm::exp(exponent_tmp);
|
||||
} else {
|
||||
|
||||
@ -210,7 +210,7 @@ public:
|
||||
/// parameters from another grid, but doesn't reallocate stuff;
|
||||
/// setup() must be called after that;
|
||||
colvar_grid(colvar_grid<T> const &g) : colvarparse(),
|
||||
nd(g.nd),
|
||||
nd(g.nd),
|
||||
nx(g.nx),
|
||||
mult(g.mult),
|
||||
data(),
|
||||
|
||||
@ -76,7 +76,7 @@ extern "C" {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DLL_MAPPING
|
||||
void CUTIL_API
|
||||
cutFree( void* ptr);
|
||||
cutFree( void* ptr);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//! Helper for bank conflict checking (should only be used with the
|
||||
|
||||
@ -65,7 +65,7 @@ static void MPI_Allreduce(const void *in, void *out, int, MPI_Datatype type,
|
||||
if (type == MPI_INT) *((int *) out) = *((int *) in);
|
||||
}
|
||||
static void MPI_Scan(const void *in, void *out, int, MPI_Datatype intype,
|
||||
MPI_Op op,MPI_Comm)
|
||||
MPI_Op op,MPI_Comm)
|
||||
{
|
||||
if (intype == MPI_INT) *((int *) out) = *((int *) in);
|
||||
}
|
||||
|
||||
@ -21,54 +21,54 @@
|
||||
#include "poemslist.h"
|
||||
|
||||
struct ChildRingData {
|
||||
List<int> * childRing;
|
||||
int entranceNodeId;
|
||||
List<int> * childRing;
|
||||
int entranceNodeId;
|
||||
};
|
||||
|
||||
struct POEMSChain{
|
||||
~POEMSChain(){
|
||||
for(int i = 0; i < childChains.GetNumElements(); i++)
|
||||
{
|
||||
delete childChains(i);
|
||||
}
|
||||
~POEMSChain(){
|
||||
for(int i = 0; i < childChains.GetNumElements(); i++)
|
||||
{
|
||||
delete childChains(i);
|
||||
}
|
||||
listOfNodes.DeleteValues();
|
||||
}
|
||||
//void printTreeStructure(int tabs);
|
||||
//void getTreeAsList(List<int> * temp);
|
||||
List<int> listOfNodes;
|
||||
List<POEMSChain> childChains;
|
||||
POEMSChain * parentChain;
|
||||
List<ChildRingData> childRings;
|
||||
}
|
||||
//void printTreeStructure(int tabs);
|
||||
//void getTreeAsList(List<int> * temp);
|
||||
List<int> listOfNodes;
|
||||
List<POEMSChain> childChains;
|
||||
POEMSChain * parentChain;
|
||||
List<ChildRingData> childRings;
|
||||
|
||||
|
||||
void printTreeStructure(int tabs){
|
||||
for(int i = 0; i < tabs; i++)
|
||||
{
|
||||
cout << "\t";
|
||||
}
|
||||
cout << "Chain: ";
|
||||
for(int i = 0; i < listOfNodes.GetNumElements(); i++)
|
||||
{
|
||||
cout << *(listOfNodes(i)) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
for(int i = 0; i < childChains.GetNumElements(); i++)
|
||||
{
|
||||
childChains(i)->printTreeStructure(tabs + 1);
|
||||
}
|
||||
}
|
||||
void getTreeAsList(List<int> * temp)
|
||||
{
|
||||
for(int i = 0; i < listOfNodes.GetNumElements(); i++)
|
||||
{
|
||||
int * integer = new int;
|
||||
*integer = *(listOfNodes(i));
|
||||
temp->Append(integer);
|
||||
}
|
||||
for(int i = 0; i < childChains.GetNumElements(); i++)
|
||||
{
|
||||
childChains(i)->getTreeAsList(temp);
|
||||
}
|
||||
}
|
||||
void printTreeStructure(int tabs){
|
||||
for(int i = 0; i < tabs; i++)
|
||||
{
|
||||
cout << "\t";
|
||||
}
|
||||
cout << "Chain: ";
|
||||
for(int i = 0; i < listOfNodes.GetNumElements(); i++)
|
||||
{
|
||||
cout << *(listOfNodes(i)) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
for(int i = 0; i < childChains.GetNumElements(); i++)
|
||||
{
|
||||
childChains(i)->printTreeStructure(tabs + 1);
|
||||
}
|
||||
}
|
||||
void getTreeAsList(List<int> * temp)
|
||||
{
|
||||
for(int i = 0; i < listOfNodes.GetNumElements(); i++)
|
||||
{
|
||||
int * integer = new int;
|
||||
*integer = *(listOfNodes(i));
|
||||
temp->Append(integer);
|
||||
}
|
||||
for(int i = 0; i < childChains.GetNumElements(); i++)
|
||||
{
|
||||
childChains(i)->getTreeAsList(temp);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -23,47 +23,47 @@
|
||||
|
||||
|
||||
struct POEMSNode {
|
||||
List<POEMSNode> links;
|
||||
List<bool> taken;
|
||||
int idNumber;
|
||||
bool visited;
|
||||
List<POEMSNode> links;
|
||||
List<bool> taken;
|
||||
int idNumber;
|
||||
bool visited;
|
||||
|
||||
~POEMSNode(){
|
||||
for(int i = 0; i < taken.GetNumElements(); i++)
|
||||
{
|
||||
delete taken(i);
|
||||
}
|
||||
};
|
||||
~POEMSNode(){
|
||||
for(int i = 0; i < taken.GetNumElements(); i++)
|
||||
{
|
||||
delete taken(i);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class SystemProcessor{
|
||||
private:
|
||||
Tree nodes;
|
||||
static void POEMSNodeDelete_cb(void *node) {
|
||||
delete (POEMSNode *) node;
|
||||
}
|
||||
List<POEMSChain> headsOfSystems;
|
||||
List<List<int> > ringsInSystem;
|
||||
POEMSNode * findSingleLink(TreeNode * aNode);
|
||||
POEMSChain * AddNewChain(POEMSNode * currentNode);
|
||||
bool setLinkVisited(POEMSNode * firstNode, POEMSNode * secondNode);
|
||||
Tree nodes;
|
||||
static void POEMSNodeDelete_cb(void *node) {
|
||||
delete (POEMSNode *) node;
|
||||
}
|
||||
List<POEMSChain> headsOfSystems;
|
||||
List<List<int> > ringsInSystem;
|
||||
POEMSNode * findSingleLink(TreeNode * aNode);
|
||||
POEMSChain * AddNewChain(POEMSNode * currentNode);
|
||||
bool setLinkVisited(POEMSNode * firstNode, POEMSNode * secondNode);
|
||||
public:
|
||||
SystemProcessor(void);
|
||||
SystemProcessor(void);
|
||||
|
||||
~SystemProcessor(void) {
|
||||
headsOfSystems.DeleteValues();
|
||||
for(int i = 0; i < ringsInSystem.GetNumElements(); i++)
|
||||
{
|
||||
for(int k = 0; k < ringsInSystem(i)->GetNumElements(); i++)
|
||||
{
|
||||
delete (*ringsInSystem(i))(k);
|
||||
}
|
||||
}
|
||||
};
|
||||
void processArray(int** links, int numLinks);
|
||||
List<POEMSChain> * getSystemData();
|
||||
int getNumberOfHeadChains();
|
||||
~SystemProcessor(void) {
|
||||
headsOfSystems.DeleteValues();
|
||||
for(int i = 0; i < ringsInSystem.GetNumElements(); i++)
|
||||
{
|
||||
for(int k = 0; k < ringsInSystem(i)->GetNumElements(); i++)
|
||||
{
|
||||
delete (*ringsInSystem(i))(k);
|
||||
}
|
||||
}
|
||||
};
|
||||
void processArray(int** links, int numLinks);
|
||||
List<POEMSChain> * getSystemData();
|
||||
int getNumberOfHeadChains();
|
||||
};
|
||||
|
||||
SystemProcessor::SystemProcessor(void){
|
||||
@ -73,145 +73,145 @@ SystemProcessor::SystemProcessor(void){
|
||||
|
||||
void SystemProcessor::processArray(int** links, int numLinks)
|
||||
{
|
||||
bool * false_var; //holds the value false; needed because a constant cannot be put into a list; the list requires a
|
||||
//reference.
|
||||
for(int i = 0; i < numLinks; i++) //go through all the links in the input array
|
||||
{
|
||||
if(!nodes.Find(links[i][0])) //if the first node in the pair is not found in the storage tree
|
||||
{
|
||||
POEMSNode * newNode = new POEMSNode; //make a new node
|
||||
// forDeletion.Append(newNode);
|
||||
newNode->idNumber = links[i][0]; //set its ID to the value
|
||||
newNode->visited = false; //set it to be unvisited
|
||||
nodes.Insert(links[i][0], links[i][0], (void *) newNode); //and add it to the tree storage structure
|
||||
}
|
||||
if(!nodes.Find(links[i][1])) //repeat process for the other half of each link
|
||||
{
|
||||
POEMSNode * newNode = new POEMSNode;
|
||||
// forDeletion.Append(newNode);
|
||||
newNode->idNumber = links[i][1];
|
||||
newNode->visited = false;
|
||||
nodes.Insert(links[i][1], links[i][1], (void *) newNode);
|
||||
}
|
||||
POEMSNode * firstNode = (POEMSNode *)nodes.Find(links[i][0]); //now that we are sure both nodes exist,
|
||||
POEMSNode * secondNode = (POEMSNode *)nodes.Find(links[i][1]); //we can get both of them out of the tree
|
||||
firstNode->links.Append(secondNode); //and add the link from the first to the second...
|
||||
false_var = new bool;
|
||||
*false_var = false; //make a new false boolean to note that the link between these two
|
||||
firstNode->taken.Append(false_var); //has not already been taken, and append it to the taken list
|
||||
secondNode->links.Append(firstNode); //repeat process for link from second node to first
|
||||
false_var = new bool;
|
||||
*false_var = false;
|
||||
secondNode->taken.Append(false_var);
|
||||
}
|
||||
bool * false_var; //holds the value false; needed because a constant cannot be put into a list; the list requires a
|
||||
//reference.
|
||||
for(int i = 0; i < numLinks; i++) //go through all the links in the input array
|
||||
{
|
||||
if(!nodes.Find(links[i][0])) //if the first node in the pair is not found in the storage tree
|
||||
{
|
||||
POEMSNode * newNode = new POEMSNode; //make a new node
|
||||
// forDeletion.Append(newNode);
|
||||
newNode->idNumber = links[i][0]; //set its ID to the value
|
||||
newNode->visited = false; //set it to be unvisited
|
||||
nodes.Insert(links[i][0], links[i][0], (void *) newNode); //and add it to the tree storage structure
|
||||
}
|
||||
if(!nodes.Find(links[i][1])) //repeat process for the other half of each link
|
||||
{
|
||||
POEMSNode * newNode = new POEMSNode;
|
||||
// forDeletion.Append(newNode);
|
||||
newNode->idNumber = links[i][1];
|
||||
newNode->visited = false;
|
||||
nodes.Insert(links[i][1], links[i][1], (void *) newNode);
|
||||
}
|
||||
POEMSNode * firstNode = (POEMSNode *)nodes.Find(links[i][0]); //now that we are sure both nodes exist,
|
||||
POEMSNode * secondNode = (POEMSNode *)nodes.Find(links[i][1]); //we can get both of them out of the tree
|
||||
firstNode->links.Append(secondNode); //and add the link from the first to the second...
|
||||
false_var = new bool;
|
||||
*false_var = false; //make a new false boolean to note that the link between these two
|
||||
firstNode->taken.Append(false_var); //has not already been taken, and append it to the taken list
|
||||
secondNode->links.Append(firstNode); //repeat process for link from second node to first
|
||||
false_var = new bool;
|
||||
*false_var = false;
|
||||
secondNode->taken.Append(false_var);
|
||||
}
|
||||
|
||||
TreeNode * temp = nodes.GetRoot(); //get the root node of the node storage tree
|
||||
POEMSNode * currentNode;
|
||||
do
|
||||
{
|
||||
currentNode = findSingleLink(temp); //find the start of the next available chain
|
||||
if(currentNode != NULL)
|
||||
{
|
||||
headsOfSystems.Append(AddNewChain(currentNode)); //and add it to the headsOfSystems list of chains
|
||||
}
|
||||
}
|
||||
while(currentNode != NULL); //repeat this until all chains have been added
|
||||
TreeNode * temp = nodes.GetRoot(); //get the root node of the node storage tree
|
||||
POEMSNode * currentNode;
|
||||
do
|
||||
{
|
||||
currentNode = findSingleLink(temp); //find the start of the next available chain
|
||||
if(currentNode != NULL)
|
||||
{
|
||||
headsOfSystems.Append(AddNewChain(currentNode)); //and add it to the headsOfSystems list of chains
|
||||
}
|
||||
}
|
||||
while(currentNode != NULL); //repeat this until all chains have been added
|
||||
}
|
||||
|
||||
POEMSChain * SystemProcessor::AddNewChain(POEMSNode * currentNode){
|
||||
if(currentNode == NULL) //Termination condition; if the currentNode is null, then return null
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
int * tmp;
|
||||
POEMSNode * nextNode = NULL; //nextNode stores the proposed next node to add to the chain. this will be checked to make sure no backtracking is occurring before being assigned as the current node.
|
||||
POEMSChain * newChain = new POEMSChain; //make a new POEMSChain object. This will be the object returned
|
||||
if(currentNode == NULL) //Termination condition; if the currentNode is null, then return null
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
int * tmp;
|
||||
POEMSNode * nextNode = NULL; //nextNode stores the proposed next node to add to the chain. this will be checked to make sure no backtracking is occurring before being assigned as the current node.
|
||||
POEMSChain * newChain = new POEMSChain; //make a new POEMSChain object. This will be the object returned
|
||||
|
||||
if(currentNode->links.GetNumElements() == 0) //if we have no links from this node, then the whole chain is only one node. Add this node to the chain and return it; mark node as visited for future reference
|
||||
{
|
||||
currentNode->visited = true;
|
||||
tmp = new int;
|
||||
*tmp = currentNode->idNumber;
|
||||
newChain->listOfNodes.Append(tmp);
|
||||
return newChain;
|
||||
}
|
||||
while(currentNode->links.GetNumElements() <= 2) //we go until we get to a node that branches, or both branches have already been taken both branches can already be taken if a loop with no spurs is found in the input data
|
||||
{
|
||||
currentNode->visited = true;
|
||||
tmp = new int;
|
||||
*tmp = currentNode->idNumber;
|
||||
newChain->listOfNodes.Append(tmp); //append the current node to the chain & mark as visited
|
||||
//cout << "Appending node " << currentNode->idNumber << " to chain" << endl;
|
||||
nextNode = currentNode->links.GetHeadElement()->value; //the next node is the first or second value stored in the links array
|
||||
//of the current node. We get the first value...
|
||||
if(!setLinkVisited(currentNode, nextNode)) //...and see if it points back to where we came from. If it does...
|
||||
{ //either way, we set this link as visited
|
||||
if(currentNode->links.GetNumElements() == 1) //if it does, then if that is the only link to this node, we're done with the chain, so append the chain to the list and return the newly created chain
|
||||
{
|
||||
// headsOfSystems.Append(newChain);
|
||||
return newChain;
|
||||
}
|
||||
nextNode = currentNode->links.GetHeadElement()->next->value;//follow the other link if there is one, so we go down the chain
|
||||
if(!setLinkVisited(currentNode, nextNode)) //mark link as followed, so we know not to backtrack
|
||||
{
|
||||
// headsOfSystems.Append(newChain);
|
||||
return newChain; //This condition, where no branches have occurred but both links have already
|
||||
//been taken can only occur in a loop with no spurs; add this loop to the
|
||||
//system (currently added as a chain for consistency), and return.
|
||||
}
|
||||
}
|
||||
currentNode = nextNode; //set the current node to be the next node in the chain
|
||||
}
|
||||
currentNode->visited = true;
|
||||
tmp = new int;
|
||||
*tmp = currentNode->idNumber;
|
||||
newChain->listOfNodes.Append(tmp); //append the last node before branch (node shared jointly with branch chains)
|
||||
//re-mark as visited, just to make sure
|
||||
ListElement<POEMSNode> * tempNode = currentNode->links.GetHeadElement(); //go through all of the links, one at a time that branch
|
||||
POEMSChain * tempChain = NULL; //temporary variable to hold data
|
||||
while(tempNode != NULL) //when we have followed all links, stop
|
||||
{
|
||||
if(setLinkVisited(tempNode->value, currentNode)) //dont backtrack, or create closed loops
|
||||
{
|
||||
tempChain = AddNewChain(tempNode->value); //Add a new chain created out of the next node down that link
|
||||
tempChain->parentChain = newChain; //set the parent to be this chain
|
||||
newChain->childChains.Append(tempChain); //append the chain to this chain's list of child chains
|
||||
}
|
||||
tempNode = tempNode->next; //go to process the next chain
|
||||
}
|
||||
//headsOfSystems.Append(newChain); //append this chain to the system list
|
||||
return newChain;
|
||||
if(currentNode->links.GetNumElements() == 0) //if we have no links from this node, then the whole chain is only one node. Add this node to the chain and return it; mark node as visited for future reference
|
||||
{
|
||||
currentNode->visited = true;
|
||||
tmp = new int;
|
||||
*tmp = currentNode->idNumber;
|
||||
newChain->listOfNodes.Append(tmp);
|
||||
return newChain;
|
||||
}
|
||||
while(currentNode->links.GetNumElements() <= 2) //we go until we get to a node that branches, or both branches have already been taken both branches can already be taken if a loop with no spurs is found in the input data
|
||||
{
|
||||
currentNode->visited = true;
|
||||
tmp = new int;
|
||||
*tmp = currentNode->idNumber;
|
||||
newChain->listOfNodes.Append(tmp); //append the current node to the chain & mark as visited
|
||||
//cout << "Appending node " << currentNode->idNumber << " to chain" << endl;
|
||||
nextNode = currentNode->links.GetHeadElement()->value; //the next node is the first or second value stored in the links array
|
||||
//of the current node. We get the first value...
|
||||
if(!setLinkVisited(currentNode, nextNode)) //...and see if it points back to where we came from. If it does...
|
||||
{ //either way, we set this link as visited
|
||||
if(currentNode->links.GetNumElements() == 1) //if it does, then if that is the only link to this node, we're done with the chain, so append the chain to the list and return the newly created chain
|
||||
{
|
||||
// headsOfSystems.Append(newChain);
|
||||
return newChain;
|
||||
}
|
||||
nextNode = currentNode->links.GetHeadElement()->next->value;//follow the other link if there is one, so we go down the chain
|
||||
if(!setLinkVisited(currentNode, nextNode)) //mark link as followed, so we know not to backtrack
|
||||
{
|
||||
// headsOfSystems.Append(newChain);
|
||||
return newChain; //This condition, where no branches have occurred but both links have already
|
||||
//been taken can only occur in a loop with no spurs; add this loop to the
|
||||
//system (currently added as a chain for consistency), and return.
|
||||
}
|
||||
}
|
||||
currentNode = nextNode; //set the current node to be the next node in the chain
|
||||
}
|
||||
currentNode->visited = true;
|
||||
tmp = new int;
|
||||
*tmp = currentNode->idNumber;
|
||||
newChain->listOfNodes.Append(tmp); //append the last node before branch (node shared jointly with branch chains)
|
||||
//re-mark as visited, just to make sure
|
||||
ListElement<POEMSNode> * tempNode = currentNode->links.GetHeadElement(); //go through all of the links, one at a time that branch
|
||||
POEMSChain * tempChain = NULL; //temporary variable to hold data
|
||||
while(tempNode != NULL) //when we have followed all links, stop
|
||||
{
|
||||
if(setLinkVisited(tempNode->value, currentNode)) //dont backtrack, or create closed loops
|
||||
{
|
||||
tempChain = AddNewChain(tempNode->value); //Add a new chain created out of the next node down that link
|
||||
tempChain->parentChain = newChain; //set the parent to be this chain
|
||||
newChain->childChains.Append(tempChain); //append the chain to this chain's list of child chains
|
||||
}
|
||||
tempNode = tempNode->next; //go to process the next chain
|
||||
}
|
||||
//headsOfSystems.Append(newChain); //append this chain to the system list
|
||||
return newChain;
|
||||
}
|
||||
|
||||
POEMSNode * SystemProcessor::findSingleLink(TreeNode * aNode)
|
||||
//This function takes the root of a search tree containing POEMSNodes and returns a POEMSNode corresponding to the start of a chain in the
|
||||
//system. It finds a node that has not been visited before, and only has one link; this node will be used as the head of the chain.
|
||||
{
|
||||
if(aNode == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
POEMSNode * returnVal = (POEMSNode *)aNode->GetAuxData(); //get the poemsnode data out of the treenode
|
||||
POEMSNode * detectLoneLoops = NULL; //is used to handle a loop that has no protruding chains
|
||||
if(returnVal->visited == false)
|
||||
{
|
||||
detectLoneLoops = returnVal; //if we find any node that has not been visited yet, save it
|
||||
}
|
||||
if(returnVal->links.GetNumElements() == 1 && returnVal->visited == false) //see if it has one element and hasnt been visited already
|
||||
{
|
||||
return returnVal; //return the node is it meets this criteria
|
||||
}
|
||||
returnVal = findSingleLink(aNode->Left()); //otherwise, check the left subtree
|
||||
if(returnVal == NULL) //and if we find nothing...
|
||||
{
|
||||
returnVal = findSingleLink(aNode->Right()); //check the right subtree
|
||||
}
|
||||
if(returnVal == NULL) //if we could not find any chains
|
||||
{
|
||||
returnVal = detectLoneLoops; //see if we found any nodes at all that havent been processed
|
||||
}
|
||||
return returnVal; //return what we find (will be NULL if no new chains are
|
||||
//found)
|
||||
if(aNode == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
POEMSNode * returnVal = (POEMSNode *)aNode->GetAuxData(); //get the poemsnode data out of the treenode
|
||||
POEMSNode * detectLoneLoops = NULL; //is used to handle a loop that has no protruding chains
|
||||
if(returnVal->visited == false)
|
||||
{
|
||||
detectLoneLoops = returnVal; //if we find any node that has not been visited yet, save it
|
||||
}
|
||||
if(returnVal->links.GetNumElements() == 1 && returnVal->visited == false) //see if it has one element and hasnt been visited already
|
||||
{
|
||||
return returnVal; //return the node is it meets this criteria
|
||||
}
|
||||
returnVal = findSingleLink(aNode->Left()); //otherwise, check the left subtree
|
||||
if(returnVal == NULL) //and if we find nothing...
|
||||
{
|
||||
returnVal = findSingleLink(aNode->Right()); //check the right subtree
|
||||
}
|
||||
if(returnVal == NULL) //if we could not find any chains
|
||||
{
|
||||
returnVal = detectLoneLoops; //see if we found any nodes at all that havent been processed
|
||||
}
|
||||
return returnVal; //return what we find (will be NULL if no new chains are
|
||||
//found)
|
||||
}
|
||||
|
||||
bool SystemProcessor::setLinkVisited(POEMSNode * firstNode, POEMSNode * secondNode)
|
||||
@ -223,65 +223,65 @@ bool SystemProcessor::setLinkVisited(POEMSNode * firstNode, POEMSNode * secondNo
|
||||
//value for that particular link. Because each link is represented twice, (once at each node in the link), both of the boolean values need
|
||||
//to be set in the event that the link has to be set as visited.
|
||||
{
|
||||
//cout << "Checking link between nodes " << firstNode->idNumber << " and " << secondNode->idNumber << "... ";
|
||||
ListElement<POEMSNode> * tmp = firstNode->links.GetHeadElement(); //get the head element of the list of pointers for node 1
|
||||
ListElement<bool> * tmp2 = firstNode->taken.GetHeadElement(); //get the head element of the list of bool isVisited flags for node 1
|
||||
while(tmp->value != NULL || tmp2->value != NULL) //go through until we reach the end of the lists
|
||||
{
|
||||
if(tmp->value == secondNode) //if we find the link to the other node
|
||||
{
|
||||
if(*(tmp2->value) == true) //if the link has already been visited
|
||||
{
|
||||
//cout << "visited already" << endl;
|
||||
return false; //return false to indicate that the link has been visited before this attempt
|
||||
}
|
||||
else //otherwise, visit it
|
||||
{
|
||||
*tmp2->value = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next; //go check next link
|
||||
tmp2 = tmp2->next;
|
||||
}
|
||||
//cout << "Checking link between nodes " << firstNode->idNumber << " and " << secondNode->idNumber << "... ";
|
||||
ListElement<POEMSNode> * tmp = firstNode->links.GetHeadElement(); //get the head element of the list of pointers for node 1
|
||||
ListElement<bool> * tmp2 = firstNode->taken.GetHeadElement(); //get the head element of the list of bool isVisited flags for node 1
|
||||
while(tmp->value != NULL || tmp2->value != NULL) //go through until we reach the end of the lists
|
||||
{
|
||||
if(tmp->value == secondNode) //if we find the link to the other node
|
||||
{
|
||||
if(*(tmp2->value) == true) //if the link has already been visited
|
||||
{
|
||||
//cout << "visited already" << endl;
|
||||
return false; //return false to indicate that the link has been visited before this attempt
|
||||
}
|
||||
else //otherwise, visit it
|
||||
{
|
||||
*tmp2->value = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next; //go check next link
|
||||
tmp2 = tmp2->next;
|
||||
}
|
||||
|
||||
tmp = secondNode->links.GetHeadElement(); //now, if the link was unvisited, we need to go set the other node's list such that
|
||||
//it also knows this link is being visited
|
||||
tmp2 = secondNode->taken.GetHeadElement();
|
||||
while(tmp->value != NULL || tmp2->value != NULL) //go through the list
|
||||
{
|
||||
if(tmp->value == firstNode) //if we find the link
|
||||
{
|
||||
if(*(tmp2->value) == true) //and it has already been visited, then signal an error; this shouldnt ever happen
|
||||
{
|
||||
cout << "Error in parsing structure! Should never reach this condition! \n" <<
|
||||
"Record of visited links out of synch between two adjacent nodes.\n";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp2->value = true; //set the appropriate value to true to indicate this link has been visited
|
||||
}
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
tmp2 = tmp2->next;
|
||||
}
|
||||
//cout << "not visited" << endl;
|
||||
return true; //return true to indicate that this is the first time the link has been visited
|
||||
tmp = secondNode->links.GetHeadElement(); //now, if the link was unvisited, we need to go set the other node's list such that
|
||||
//it also knows this link is being visited
|
||||
tmp2 = secondNode->taken.GetHeadElement();
|
||||
while(tmp->value != NULL || tmp2->value != NULL) //go through the list
|
||||
{
|
||||
if(tmp->value == firstNode) //if we find the link
|
||||
{
|
||||
if(*(tmp2->value) == true) //and it has already been visited, then signal an error; this shouldnt ever happen
|
||||
{
|
||||
cout << "Error in parsing structure! Should never reach this condition! \n" <<
|
||||
"Record of visited links out of synch between two adjacent nodes.\n";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp2->value = true; //set the appropriate value to true to indicate this link has been visited
|
||||
}
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
tmp2 = tmp2->next;
|
||||
}
|
||||
//cout << "not visited" << endl;
|
||||
return true; //return true to indicate that this is the first time the link has been visited
|
||||
}
|
||||
|
||||
List<POEMSChain> * SystemProcessor::getSystemData(void) //Gets the list of POEMSChains that comprise the system. Might eventually only
|
||||
//return chains linked to the reference plane, but currently returns every chain
|
||||
//in the system.
|
||||
List<POEMSChain> * SystemProcessor::getSystemData(void) //Gets the list of POEMSChains that comprise the system. Might eventually only
|
||||
//return chains linked to the reference plane, but currently returns every chain
|
||||
//in the system.
|
||||
{
|
||||
return &headsOfSystems;
|
||||
return &headsOfSystems;
|
||||
}
|
||||
|
||||
int SystemProcessor::getNumberOfHeadChains(void) //This function isnt implemented yet, and might be taken out entirely; this was a holdover
|
||||
//from when I intended to return an array of chain pointers, rather than a list of chains
|
||||
//It will probably be deleted once I finish figuring out exactly what needs to be returned
|
||||
//from when I intended to return an array of chain pointers, rather than a list of chains
|
||||
//It will probably be deleted once I finish figuring out exactly what needs to be returned
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
*_________________________________________________________________________*
|
||||
* POEMS: PARALLELIZABLE OPEN SOURCE EFFICIENT MULTIBODY SOFTWARE *
|
||||
* DESCRIPTION: SEE READ-ME *
|
||||
* FILE NAME: body23joint.h *
|
||||
* FILE NAME: body23joint.h *
|
||||
* AUTHORS: See Author List *
|
||||
* GRANTS: See Grants List *
|
||||
* COPYRIGHT: (C) 2005 by Authors as listed in Author's List *
|
||||
|
||||
@ -62,23 +62,23 @@ public:
|
||||
void BasicMin(double& value, int& index);
|
||||
|
||||
// fast matrix operations
|
||||
friend void FastQuaternions(ColMatrix& q, Mat3x3& C);
|
||||
friend void FastInvQuaternions(Mat3x3& C, ColMatrix& q);
|
||||
friend void FastQuaternionDerivatives(ColMatrix& q, ColMatrix& omega, ColMatrix& qdot);
|
||||
friend void FastTMult(Matrix& A, Vect6& B, ColMatrix& C);
|
||||
friend void FastMult(Matrix& A, ColMatrix& B, Vect6& C);
|
||||
friend void FastAssign(ColMatrix& A, ColMatrix& C);
|
||||
friend void FastQuaternions(ColMatrix& q, Mat3x3& C);
|
||||
friend void FastInvQuaternions(Mat3x3& C, ColMatrix& q);
|
||||
friend void FastQuaternionDerivatives(ColMatrix& q, ColMatrix& omega, ColMatrix& qdot);
|
||||
friend void FastTMult(Matrix& A, Vect6& B, ColMatrix& C);
|
||||
friend void FastMult(Matrix& A, ColMatrix& B, Vect6& C);
|
||||
friend void FastAssign(ColMatrix& A, ColMatrix& C);
|
||||
|
||||
friend void FastMult(Mat3x3& A, ColMatrix& B, Vect3& C);
|
||||
friend void FastMult(Mat3x3& A, Vect3& B, ColMatrix& C);
|
||||
friend void FastAssign(ColMatrix&A, Vect3& C);
|
||||
friend void FastMult(Mat3x3& A, ColMatrix& B, Vect3& C);
|
||||
friend void FastMult(Mat3x3& A, Vect3& B, ColMatrix& C);
|
||||
friend void FastAssign(ColMatrix&A, Vect3& C);
|
||||
|
||||
friend void EP_Derivatives(ColMatrix& q, ColMatrix& u, ColMatrix& qdot);
|
||||
friend void EP_Transformation(ColMatrix& q, Mat3x3& C);
|
||||
friend void EP_FromTransformation(ColMatrix& q, Mat3x3& C);
|
||||
friend void EP_Normalize(ColMatrix& q);
|
||||
friend void EPdotdot_udot(ColMatrix& Audot, ColMatrix& Aqdot, ColMatrix& Aq,ColMatrix& Aqddot);
|
||||
friend void qdot_to_u(ColMatrix& q, ColMatrix& u, ColMatrix& qdot);
|
||||
friend void EP_Derivatives(ColMatrix& q, ColMatrix& u, ColMatrix& qdot);
|
||||
friend void EP_Transformation(ColMatrix& q, Mat3x3& C);
|
||||
friend void EP_FromTransformation(ColMatrix& q, Mat3x3& C);
|
||||
friend void EP_Normalize(ColMatrix& q);
|
||||
friend void EPdotdot_udot(ColMatrix& Audot, ColMatrix& Aqdot, ColMatrix& Aq,ColMatrix& Aqddot);
|
||||
friend void qdot_to_u(ColMatrix& q, ColMatrix& u, ColMatrix& qdot);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
*_________________________________________________________________________*
|
||||
* POEMS: PARALLELIZABLE OPEN SOURCE EFFICIENT MULTIBODY SOFTWARE *
|
||||
* DESCRIPTION: SEE READ-ME *
|
||||
* FILE NAME: defines.h *
|
||||
* FILE NAME: defines.h *
|
||||
* AUTHORS: See Author List *
|
||||
* GRANTS: See Grants List *
|
||||
* COPYRIGHT: (C) 2005 by Authors as listed in Author's List *
|
||||
|
||||
@ -44,22 +44,22 @@ Mat4x4 Inverse(Mat4x4& A);
|
||||
Mat6x6 Inverse(Mat6x6& A);
|
||||
|
||||
// overloaded addition
|
||||
Matrix operator+ (const VirtualMatrix &A, const VirtualMatrix &B); // addition
|
||||
//Mat3x3 operator+ (const Mat3x3 &A, const Mat3x3 &B); // addition
|
||||
//Matrix operator+ (const VirtualMatrix &A, const VirtualMatrix &B); // addition
|
||||
Matrix operator+ (const VirtualMatrix &A, const VirtualMatrix &B); // addition
|
||||
//Mat3x3 operator+ (const Mat3x3 &A, const Mat3x3 &B); // addition
|
||||
//Matrix operator+ (const VirtualMatrix &A, const VirtualMatrix &B); // addition
|
||||
|
||||
// overloaded subtraction
|
||||
Matrix operator- (const VirtualMatrix &A, const VirtualMatrix &B); // subtraction
|
||||
Matrix operator- (const VirtualMatrix &A, const VirtualMatrix &B); // subtraction
|
||||
|
||||
// overloaded matrix multiplication
|
||||
Matrix operator* (const VirtualMatrix &A, const VirtualMatrix &B); // multiplication
|
||||
|
||||
// overloaded scalar-matrix multiplication
|
||||
Matrix operator* (const VirtualMatrix &A, double b); // overloaded *
|
||||
Matrix operator* (double b, const VirtualMatrix &A); // overloaded *
|
||||
Matrix operator* (const VirtualMatrix &A, double b); // overloaded *
|
||||
Matrix operator* (double b, const VirtualMatrix &A); // overloaded *
|
||||
|
||||
// overloaded negative
|
||||
Matrix operator- (const VirtualMatrix &A); // negative
|
||||
Matrix operator- (const VirtualMatrix &A); // negative
|
||||
|
||||
Vect3 Cross(Vect3& a, Vect3& b);
|
||||
Mat3x3 CrossMat(Vect3& a);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
*_________________________________________________________________________*
|
||||
* POEMS: PARALLELIZABLE OPEN SOURCE EFFICIENT MULTIBODY SOFTWARE *
|
||||
* DESCRIPTION: SEE READ-ME *
|
||||
* FILE NAME: mixedjoint.h *
|
||||
* FILE NAME: mixedjoint.h *
|
||||
* AUTHORS: See Author List *
|
||||
* GRANTS: See Grants List *
|
||||
* COPYRIGHT: (C) 2005 by Authors as listed in Author's List *
|
||||
|
||||
@ -92,7 +92,7 @@ public:
|
||||
void Setup();
|
||||
void SetupInertialFrame();
|
||||
void LocalKinematics();
|
||||
void LocalTriangularization(Vect3& Torque, Vect3& Force);
|
||||
void LocalTriangularization(Vect3& Torque, Vect3& Force);
|
||||
void LocalForwardSubstitution();
|
||||
};
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ class OnSolver : public Solver {
|
||||
OnBody** bodyarray;
|
||||
ColMatrix** q;
|
||||
ColMatrix** qdot;
|
||||
ColMatrix** qdotdot;
|
||||
ColMatrix** qdotdot;
|
||||
ColMatrix** u;
|
||||
ColMatrix** udot;
|
||||
|
||||
@ -40,7 +40,7 @@ class OnSolver : public Solver {
|
||||
void DeleteModel();
|
||||
int CreateTopologyArray(int i, OnBody* body);
|
||||
void CreateStateMatrixMaps();
|
||||
void GetType();
|
||||
void GetType();
|
||||
public:
|
||||
OnSolver();
|
||||
~OnSolver();
|
||||
|
||||
@ -90,9 +90,9 @@ template<class S> List<S>::~List(){
|
||||
|
||||
template<class S> void List<S>::Append(List<S> * listToAppend)
|
||||
{
|
||||
tail->next = listToAppend->head;
|
||||
listToAppend->head->prev = tail;
|
||||
tail = listToAppend->tail;
|
||||
tail->next = listToAppend->head;
|
||||
listToAppend->head->prev = tail;
|
||||
tail = listToAppend->tail;
|
||||
}
|
||||
|
||||
template<class S> int List<S>::GetNumElements(){
|
||||
@ -104,7 +104,7 @@ template<class S> ListElement<S>* List<S>::GetHeadElement(){
|
||||
}
|
||||
|
||||
template<class S> ListElement<S>* List<S>::GetTailElement(){
|
||||
return tail;
|
||||
return tail;
|
||||
}
|
||||
|
||||
|
||||
@ -145,14 +145,14 @@ template<class S> ListElement<S>* List<S>::Append(S* v){
|
||||
if(numelements==1)
|
||||
head = tail = ele;
|
||||
else{
|
||||
/*
|
||||
/*
|
||||
tail->next = ele;
|
||||
ele->prev = tail;
|
||||
tail = ele;*/
|
||||
tail = ele;*/
|
||||
|
||||
ele->prev = tail;
|
||||
tail = ele;
|
||||
ele->prev->next = ele;
|
||||
ele->prev = tail;
|
||||
tail = ele;
|
||||
ele->prev->next = ele;
|
||||
|
||||
}
|
||||
return ele;
|
||||
@ -170,9 +170,9 @@ template<class S> ListElement<S>* List<S>::Prepend(S* v){
|
||||
if(numelements==1)
|
||||
head = tail = ele;
|
||||
else{
|
||||
ele->next = head;
|
||||
head = ele;
|
||||
ele->next->prev = ele;
|
||||
ele->next = head;
|
||||
head = ele;
|
||||
ele->next->prev = ele;
|
||||
}
|
||||
return ele;
|
||||
}
|
||||
@ -214,15 +214,15 @@ template<class S> void List<S>::RemoveElementAndDeleteValue(ListElement<S>* ele)
|
||||
}
|
||||
|
||||
template<class S> void List<S>::PrintList(){
|
||||
cout<<"Printing List "<<endl;
|
||||
ListElement<S>* ele = head;
|
||||
cout<<*(ele->value)<<" ";
|
||||
ele = ele->next;
|
||||
for(int k =2; k<numelements; k++){
|
||||
cout<<*(ele->value)<<" ";
|
||||
ele = ele->next;
|
||||
}
|
||||
cout<<*(ele->value)<<endl;
|
||||
cout<<"Printing List "<<endl;
|
||||
ListElement<S>* ele = head;
|
||||
cout<<*(ele->value)<<" ";
|
||||
ele = ele->next;
|
||||
for(int k =2; k<numelements; k++){
|
||||
cout<<*(ele->value)<<" ";
|
||||
ele = ele->next;
|
||||
}
|
||||
cout<<*(ele->value)<<endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -45,26 +45,26 @@ void PrintTree (TreeNode *t, int level);
|
||||
// postorder recursive scan of the nodes in a tree
|
||||
void Postorder (TreeNode *t, void visit(TreeNode* &t))
|
||||
{
|
||||
// the recursive scan terminates on a empty subtree
|
||||
if (t != NULL)
|
||||
{
|
||||
Postorder(t->Left(), visit); // descend left
|
||||
Postorder(t->Right(), visit); // descend right
|
||||
visit(t); // visit the node
|
||||
}
|
||||
// the recursive scan terminates on a empty subtree
|
||||
if (t != NULL)
|
||||
{
|
||||
Postorder(t->Left(), visit); // descend left
|
||||
Postorder(t->Right(), visit); // descend right
|
||||
visit(t); // visit the node
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// preorder recursive scan of the nodes in a tree
|
||||
void Preorder (TreeNode *t, void visit(TreeNode* &t))
|
||||
{
|
||||
// the recursive scan terminates on a empty subtree
|
||||
if (t != NULL)
|
||||
{
|
||||
visit(t); // visit the node
|
||||
Preorder(t->Left(), visit); // descend left
|
||||
Preorder(t->Right(), visit); // descend right
|
||||
}
|
||||
// the recursive scan terminates on a empty subtree
|
||||
if (t != NULL)
|
||||
{
|
||||
visit(t); // visit the node
|
||||
Preorder(t->Left(), visit); // descend left
|
||||
Preorder(t->Right(), visit); // descend right
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -72,21 +72,21 @@ void Preorder (TreeNode *t, void visit(TreeNode* &t))
|
||||
// The pointers have default value NULL
|
||||
TreeNode *GetTreeNode(int item,TreeNode *lptr,TreeNode *rptr)
|
||||
{
|
||||
TreeNode *p;
|
||||
TreeNode *p;
|
||||
|
||||
// call new to allocate the new node
|
||||
// pass parameters lptr and rptr to the function
|
||||
p = new TreeNode(item, lptr, rptr);
|
||||
// call new to allocate the new node
|
||||
// pass parameters lptr and rptr to the function
|
||||
p = new TreeNode(item, lptr, rptr);
|
||||
|
||||
// if insufficient memory, terminatewith an error message
|
||||
if (p == NULL)
|
||||
{
|
||||
cerr << "Memory allocation failure!\n";
|
||||
exit(1);
|
||||
}
|
||||
// if insufficient memory, terminatewith an error message
|
||||
if (p == NULL)
|
||||
{
|
||||
cerr << "Memory allocation failure!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// return the pointer to the system generated memory
|
||||
return p;
|
||||
// return the pointer to the system generated memory
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ TreeNode *GetTreeNode(int item,TreeNode *lptr,TreeNode *rptr)
|
||||
|
||||
void FreeTreeNode(TreeNode *p)
|
||||
{
|
||||
delete p;
|
||||
delete p;
|
||||
}
|
||||
|
||||
|
||||
@ -102,17 +102,17 @@ void FreeTreeNode(TreeNode *p)
|
||||
// tests whether the node is a leaf node
|
||||
void CountLeaf (TreeNode *t, int& count)
|
||||
{
|
||||
//use postorder descent
|
||||
if(t !=NULL)
|
||||
{
|
||||
CountLeaf(t->Left(), count); // descend left
|
||||
CountLeaf(t->Right(), count); // descend right
|
||||
//use postorder descent
|
||||
if(t !=NULL)
|
||||
{
|
||||
CountLeaf(t->Left(), count); // descend left
|
||||
CountLeaf(t->Right(), count); // descend right
|
||||
|
||||
// check if node t is a leaf node (no descendants)
|
||||
// if so, increment the variable count
|
||||
if (t->Left() == NULL && t->Right() == NULL)
|
||||
count++;
|
||||
}
|
||||
// check if node t is a leaf node (no descendants)
|
||||
// if so, increment the variable count
|
||||
if (t->Left() == NULL && t->Right() == NULL)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -122,41 +122,41 @@ void CountLeaf (TreeNode *t, int& count)
|
||||
// the depth of an empty tree is -1
|
||||
int Depth (TreeNode *t)
|
||||
{
|
||||
int depthLeft, depthRight, depthval;
|
||||
int depthLeft, depthRight, depthval;
|
||||
|
||||
if (t == NULL)
|
||||
depthval = -1;
|
||||
else
|
||||
{
|
||||
depthLeft = Depth(t->Left());
|
||||
depthRight = Depth(t->Right());
|
||||
depthval = 1+(depthLeft > depthRight?depthLeft:depthRight);
|
||||
}
|
||||
return depthval;
|
||||
if (t == NULL)
|
||||
depthval = -1;
|
||||
else
|
||||
{
|
||||
depthLeft = Depth(t->Left());
|
||||
depthRight = Depth(t->Right());
|
||||
depthval = 1+(depthLeft > depthRight?depthLeft:depthRight);
|
||||
}
|
||||
return depthval;
|
||||
}
|
||||
|
||||
void IndentBlanks(int num)
|
||||
{
|
||||
// const int indentblock = 6;
|
||||
// const int indentblock = 6;
|
||||
|
||||
for(int i = 0; i < num; i++)
|
||||
cout << " ";
|
||||
for(int i = 0; i < num; i++)
|
||||
cout << " ";
|
||||
}
|
||||
|
||||
void PrintTree (TreeNode *t, int level)
|
||||
{
|
||||
//print tree with root t, as long as t!=NULL
|
||||
if (t != NULL)
|
||||
{
|
||||
int indentUnit = 5;
|
||||
// print right branch of tree t
|
||||
PrintTree(t->Right(),level + 1);
|
||||
// indent to current level; output node data
|
||||
IndentBlanks(indentUnit*level);
|
||||
cout << t->GetData() << endl;
|
||||
// print left branch of tree t
|
||||
PrintTree(t->Left(),level + 1);
|
||||
}
|
||||
//print tree with root t, as long as t!=NULL
|
||||
if (t != NULL)
|
||||
{
|
||||
int indentUnit = 5;
|
||||
// print right branch of tree t
|
||||
PrintTree(t->Right(),level + 1);
|
||||
// indent to current level; output node data
|
||||
IndentBlanks(indentUnit*level);
|
||||
cout << t->GetData() << endl;
|
||||
// print left branch of tree t
|
||||
PrintTree(t->Left(),level + 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -31,74 +31,74 @@ const int rightheavy = 1;
|
||||
|
||||
class Tree{
|
||||
protected:
|
||||
// pointer to tree root and node most recently accessed
|
||||
TreeNode *root;
|
||||
TreeNode *current;
|
||||
// pointer to tree root and node most recently accessed
|
||||
TreeNode *root;
|
||||
TreeNode *current;
|
||||
|
||||
// number of elements in the tree
|
||||
int size;
|
||||
// used by the copy constructor and assignment operator
|
||||
TreeNode *CopyTree(TreeNode *t);
|
||||
// number of elements in the tree
|
||||
int size;
|
||||
// used by the copy constructor and assignment operator
|
||||
TreeNode *CopyTree(TreeNode *t);
|
||||
|
||||
// callback function to delete aux data
|
||||
void (*DeleteAuxData)(void *);
|
||||
|
||||
// used by insert and delete method to re-establish
|
||||
// the avl conditions after a node is added or deleted
|
||||
// from a subtree
|
||||
void SingleRotateLeft (TreeNode* &p);
|
||||
void SingleRotateRight (TreeNode* &p);
|
||||
void DoubleRotateLeft (TreeNode* &p);
|
||||
void DoubleRotateRight (TreeNode* &p);
|
||||
void UpdateLeftTree (TreeNode* &p, int &reviseBalanceFactor);
|
||||
void UpdateRightTree (TreeNode* &p, int &reviseBalanceFactor);
|
||||
// used by insert and delete method to re-establish
|
||||
// the avl conditions after a node is added or deleted
|
||||
// from a subtree
|
||||
void SingleRotateLeft (TreeNode* &p);
|
||||
void SingleRotateRight (TreeNode* &p);
|
||||
void DoubleRotateLeft (TreeNode* &p);
|
||||
void DoubleRotateRight (TreeNode* &p);
|
||||
void UpdateLeftTree (TreeNode* &p, int &reviseBalanceFactor);
|
||||
void UpdateRightTree (TreeNode* &p, int &reviseBalanceFactor);
|
||||
|
||||
|
||||
// used by destructor, assignment operator and ClearList
|
||||
void DeleteTree(TreeNode *t);
|
||||
void ClearTree(TreeNode * &t);
|
||||
// used by destructor, assignment operator and ClearList
|
||||
void DeleteTree(TreeNode *t);
|
||||
void ClearTree(TreeNode * &t);
|
||||
|
||||
// locate a node with data item and its parent in tree
|
||||
// used by Find and Delete
|
||||
TreeNode *FindNode(const int& item, TreeNode* & parent) const;
|
||||
// locate a node with data item and its parent in tree
|
||||
// used by Find and Delete
|
||||
TreeNode *FindNode(const int& item, TreeNode* & parent) const;
|
||||
|
||||
public:
|
||||
// constructor, destructor
|
||||
Tree(void);
|
||||
~Tree(void)
|
||||
{
|
||||
ClearTree(root);
|
||||
};
|
||||
// constructor, destructor
|
||||
Tree(void);
|
||||
~Tree(void)
|
||||
{
|
||||
ClearTree(root);
|
||||
};
|
||||
|
||||
// assignment operator
|
||||
Tree& operator= (const Tree& rhs);
|
||||
// assignment operator
|
||||
Tree& operator= (const Tree& rhs);
|
||||
|
||||
// standard list handling methods
|
||||
void * Find(int& item);
|
||||
void * GetAuxData(int item) {
|
||||
// standard list handling methods
|
||||
void * Find(int& item);
|
||||
void * GetAuxData(int item) {
|
||||
return (void *)(FindNode(item, root)->GetAuxData());
|
||||
}
|
||||
void SetDeleteAuxData(void (*callback)(void *)) {
|
||||
DeleteAuxData = callback;
|
||||
}
|
||||
|
||||
void Insert(const int& item, const int& data, void * AuxData = NULL);
|
||||
void Delete(const int& item);
|
||||
void AVLInsert(TreeNode* &tree, TreeNode* newNode, int &reviseBalanceFactor);
|
||||
void ClearList(void);
|
||||
void Insert(const int& item, const int& data, void * AuxData = NULL);
|
||||
void Delete(const int& item);
|
||||
void AVLInsert(TreeNode* &tree, TreeNode* newNode, int &reviseBalanceFactor);
|
||||
void ClearList(void);
|
||||
|
||||
// tree specific methods
|
||||
void Update(const int& item);
|
||||
TreeNode *GetRoot(void) const;
|
||||
// tree specific methods
|
||||
void Update(const int& item);
|
||||
TreeNode *GetRoot(void) const;
|
||||
};
|
||||
|
||||
|
||||
// constructor
|
||||
Tree::Tree(void)
|
||||
{
|
||||
root = 0;
|
||||
current = 0;
|
||||
size = 0;
|
||||
root = 0;
|
||||
current = 0;
|
||||
size = 0;
|
||||
DeleteAuxData = NULL;
|
||||
}
|
||||
|
||||
@ -107,418 +107,418 @@ Tree::Tree(void)
|
||||
// return root pointer
|
||||
TreeNode *Tree::GetRoot(void) const
|
||||
{
|
||||
return root;
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
// assignment operator
|
||||
Tree& Tree::operator = (const Tree& rhs)
|
||||
{
|
||||
// can't copy a tree to itself
|
||||
if (this == &rhs)
|
||||
return *this;
|
||||
// can't copy a tree to itself
|
||||
if (this == &rhs)
|
||||
return *this;
|
||||
|
||||
// clear current tree. copy new tree into current object
|
||||
ClearList();
|
||||
root = CopyTree(rhs.root);
|
||||
// clear current tree. copy new tree into current object
|
||||
ClearList();
|
||||
root = CopyTree(rhs.root);
|
||||
|
||||
// assign current to root and set the tree size
|
||||
current = root;
|
||||
size = rhs.size;
|
||||
// assign current to root and set the tree size
|
||||
current = root;
|
||||
size = rhs.size;
|
||||
|
||||
// return reference to current object
|
||||
return *this;
|
||||
// return reference to current object
|
||||
return *this;
|
||||
}
|
||||
|
||||
// search for data item in the tree. if found, return its node
|
||||
// address and a pointer to its parent; otherwise, return NULL
|
||||
TreeNode *Tree::FindNode(const int& item,
|
||||
TreeNode* & parent) const
|
||||
TreeNode* & parent) const
|
||||
{
|
||||
// cycle t through the tree starting with root
|
||||
TreeNode *t = root;
|
||||
// cycle t through the tree starting with root
|
||||
TreeNode *t = root;
|
||||
|
||||
// the parent of the root is NULL
|
||||
parent = NULL;
|
||||
// the parent of the root is NULL
|
||||
parent = NULL;
|
||||
|
||||
// terminate on empty subtree
|
||||
while(t != NULL)
|
||||
{
|
||||
// stop on a match
|
||||
if (item == t->data)
|
||||
break;
|
||||
else
|
||||
{
|
||||
// update the parent pointer and move right of left
|
||||
parent = t;
|
||||
if (item < t->data)
|
||||
t = t->left;
|
||||
else
|
||||
t = t->right;
|
||||
}
|
||||
}
|
||||
// terminate on empty subtree
|
||||
while(t != NULL)
|
||||
{
|
||||
// stop on a match
|
||||
if (item == t->data)
|
||||
break;
|
||||
else
|
||||
{
|
||||
// update the parent pointer and move right of left
|
||||
parent = t;
|
||||
if (item < t->data)
|
||||
t = t->left;
|
||||
else
|
||||
t = t->right;
|
||||
}
|
||||
}
|
||||
|
||||
// return pointer to node; NULL if not found
|
||||
return t;
|
||||
// return pointer to node; NULL if not found
|
||||
return t;
|
||||
}
|
||||
|
||||
// search for item. if found, assign the node data to item
|
||||
void * Tree::Find(int& item)
|
||||
{
|
||||
// we use FindNode, which requires a parent parameter
|
||||
TreeNode *parent;
|
||||
// we use FindNode, which requires a parent parameter
|
||||
TreeNode *parent;
|
||||
|
||||
// search tree for item. assign matching node to current
|
||||
current = FindNode (item, parent);
|
||||
// search tree for item. assign matching node to current
|
||||
current = FindNode (item, parent);
|
||||
|
||||
// if item found, assign data to item and return True
|
||||
if (current != NULL)
|
||||
{
|
||||
item = current->data;
|
||||
// if item found, assign data to item and return True
|
||||
if (current != NULL)
|
||||
{
|
||||
item = current->data;
|
||||
return current->GetAuxData();
|
||||
}
|
||||
else
|
||||
// item not found in the tree. return False
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
// item not found in the tree. return False
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void Tree::Insert(const int& item, const int& data, void * AuxData)
|
||||
{
|
||||
// declare AVL tree node pointer; using base class method
|
||||
// GetRoot. cast to larger node and assign root pointer
|
||||
TreeNode *treeRoot, *newNode;
|
||||
treeRoot = GetRoot();
|
||||
// declare AVL tree node pointer; using base class method
|
||||
// GetRoot. cast to larger node and assign root pointer
|
||||
TreeNode *treeRoot, *newNode;
|
||||
treeRoot = GetRoot();
|
||||
|
||||
// flag used by AVLInsert to rebalance nodes
|
||||
int reviseBalanceFactor = 0;
|
||||
// flag used by AVLInsert to rebalance nodes
|
||||
int reviseBalanceFactor = 0;
|
||||
|
||||
// get a new AVL tree node with empty pointer fields
|
||||
newNode = GetTreeNode(item,NULL,NULL);
|
||||
newNode->data = data;
|
||||
newNode->SetAuxData(AuxData);
|
||||
// call recursive routine to actually insert the element
|
||||
AVLInsert(treeRoot, newNode, reviseBalanceFactor);
|
||||
// get a new AVL tree node with empty pointer fields
|
||||
newNode = GetTreeNode(item,NULL,NULL);
|
||||
newNode->data = data;
|
||||
newNode->SetAuxData(AuxData);
|
||||
// call recursive routine to actually insert the element
|
||||
AVLInsert(treeRoot, newNode, reviseBalanceFactor);
|
||||
|
||||
// assign new values to data members in the base class
|
||||
root = treeRoot;
|
||||
current = newNode;
|
||||
size++;
|
||||
// assign new values to data members in the base class
|
||||
root = treeRoot;
|
||||
current = newNode;
|
||||
size++;
|
||||
|
||||
}
|
||||
|
||||
void Tree::AVLInsert(TreeNode *&tree, TreeNode *newNode, int &reviseBalanceFactor)
|
||||
{
|
||||
// flag indicates change node's balanceFactor will occur
|
||||
int rebalanceCurrNode;
|
||||
// flag indicates change node's balanceFactor will occur
|
||||
int rebalanceCurrNode;
|
||||
|
||||
// scan reaches an empty tree; time to insert the new node
|
||||
if (tree == NULL)
|
||||
{
|
||||
// update the parent to point at newNode
|
||||
tree = newNode;
|
||||
// scan reaches an empty tree; time to insert the new node
|
||||
if (tree == NULL)
|
||||
{
|
||||
// update the parent to point at newNode
|
||||
tree = newNode;
|
||||
|
||||
// assign balanceFactor = 0 to new node
|
||||
tree->balanceFactor = balanced;
|
||||
// broadcast message; balanceFactor value is modified
|
||||
reviseBalanceFactor = 1;
|
||||
}
|
||||
// recursively move left if new data < current data
|
||||
else if (newNode->data < tree->data)
|
||||
{
|
||||
AVLInsert(tree->left,newNode,rebalanceCurrNode);
|
||||
// check if balanceFactor must be updated.
|
||||
if (rebalanceCurrNode)
|
||||
{
|
||||
// went left from node that is left heavy. will
|
||||
// violate AVL condition; use rotation (case 3)
|
||||
if (tree->balanceFactor == leftheavy)
|
||||
UpdateLeftTree(tree,reviseBalanceFactor);
|
||||
// assign balanceFactor = 0 to new node
|
||||
tree->balanceFactor = balanced;
|
||||
// broadcast message; balanceFactor value is modified
|
||||
reviseBalanceFactor = 1;
|
||||
}
|
||||
// recursively move left if new data < current data
|
||||
else if (newNode->data < tree->data)
|
||||
{
|
||||
AVLInsert(tree->left,newNode,rebalanceCurrNode);
|
||||
// check if balanceFactor must be updated.
|
||||
if (rebalanceCurrNode)
|
||||
{
|
||||
// went left from node that is left heavy. will
|
||||
// violate AVL condition; use rotation (case 3)
|
||||
if (tree->balanceFactor == leftheavy)
|
||||
UpdateLeftTree(tree,reviseBalanceFactor);
|
||||
|
||||
// went left from balanced node. will create
|
||||
// node left on the left. AVL condition OK (case 1)
|
||||
else if (tree->balanceFactor == balanced)
|
||||
{
|
||||
tree->balanceFactor = leftheavy;
|
||||
reviseBalanceFactor = 1;
|
||||
}
|
||||
// went left from node that is right heavy. will
|
||||
// balance the node. AVL condition OK (case 2)
|
||||
else
|
||||
{
|
||||
tree->balanceFactor = balanced;
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
}
|
||||
// went left from balanced node. will create
|
||||
// node left on the left. AVL condition OK (case 1)
|
||||
else if (tree->balanceFactor == balanced)
|
||||
{
|
||||
tree->balanceFactor = leftheavy;
|
||||
reviseBalanceFactor = 1;
|
||||
}
|
||||
// went left from node that is right heavy. will
|
||||
// balance the node. AVL condition OK (case 2)
|
||||
else
|
||||
{
|
||||
tree->balanceFactor = balanced;
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
// no balancing occurs; do not ask previous nodes
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
// otherwise recursively move right
|
||||
else
|
||||
{
|
||||
AVLInsert(tree->right, newNode, rebalanceCurrNode);
|
||||
// check if balanceFactor must be updated.
|
||||
if (rebalanceCurrNode)
|
||||
{
|
||||
// went right from node that is left heavy. wil;
|
||||
// balance the node. AVL condition OK (case 2)
|
||||
if (tree->balanceFactor == leftheavy)
|
||||
{
|
||||
// scanning right subtree. node heavy on left.
|
||||
// the node will become balanced
|
||||
tree->balanceFactor = balanced;
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
// went right from balanced node. will create
|
||||
// node heavy on the right. AVL condition OK (case 1)
|
||||
else if (tree->balanceFactor == balanced)
|
||||
{
|
||||
// node is balanced; will become heavy on right
|
||||
tree->balanceFactor = rightheavy;
|
||||
reviseBalanceFactor = 1;
|
||||
}
|
||||
// went right from node that is right heavy. will
|
||||
// violate AVL condition; use rotation (case 3)
|
||||
else
|
||||
UpdateRightTree(tree, reviseBalanceFactor);
|
||||
}
|
||||
else
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
{
|
||||
AVLInsert(tree->right, newNode, rebalanceCurrNode);
|
||||
// check if balanceFactor must be updated.
|
||||
if (rebalanceCurrNode)
|
||||
{
|
||||
// went right from node that is left heavy. wil;
|
||||
// balance the node. AVL condition OK (case 2)
|
||||
if (tree->balanceFactor == leftheavy)
|
||||
{
|
||||
// scanning right subtree. node heavy on left.
|
||||
// the node will become balanced
|
||||
tree->balanceFactor = balanced;
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
// went right from balanced node. will create
|
||||
// node heavy on the right. AVL condition OK (case 1)
|
||||
else if (tree->balanceFactor == balanced)
|
||||
{
|
||||
// node is balanced; will become heavy on right
|
||||
tree->balanceFactor = rightheavy;
|
||||
reviseBalanceFactor = 1;
|
||||
}
|
||||
// went right from node that is right heavy. will
|
||||
// violate AVL condition; use rotation (case 3)
|
||||
else
|
||||
UpdateRightTree(tree, reviseBalanceFactor);
|
||||
}
|
||||
else
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Tree::UpdateLeftTree (TreeNode* &p, int &reviseBalanceFactor)
|
||||
{
|
||||
TreeNode *lc;
|
||||
TreeNode *lc;
|
||||
|
||||
lc = p->Left(); // left subtree is also heavy
|
||||
if (lc->balanceFactor == leftheavy)
|
||||
{
|
||||
SingleRotateRight(p);
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
// is right subtree heavy?
|
||||
else if (lc->balanceFactor == rightheavy)
|
||||
{
|
||||
// make a double rotation
|
||||
DoubleRotateRight(p);
|
||||
// root is now balance
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
lc = p->Left(); // left subtree is also heavy
|
||||
if (lc->balanceFactor == leftheavy)
|
||||
{
|
||||
SingleRotateRight(p);
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
// is right subtree heavy?
|
||||
else if (lc->balanceFactor == rightheavy)
|
||||
{
|
||||
// make a double rotation
|
||||
DoubleRotateRight(p);
|
||||
// root is now balance
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Tree::UpdateRightTree (TreeNode* &p, int &reviseBalanceFactor)
|
||||
{
|
||||
TreeNode *lc;
|
||||
TreeNode *lc;
|
||||
|
||||
lc = p->Right(); // right subtree is also heavy
|
||||
if (lc->balanceFactor == rightheavy)
|
||||
{
|
||||
SingleRotateLeft(p);
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
// is left subtree heavy?
|
||||
else if (lc->balanceFactor == leftheavy)
|
||||
{
|
||||
// make a double rotation
|
||||
DoubleRotateLeft(p);
|
||||
// root is now balance
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
lc = p->Right(); // right subtree is also heavy
|
||||
if (lc->balanceFactor == rightheavy)
|
||||
{
|
||||
SingleRotateLeft(p);
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
// is left subtree heavy?
|
||||
else if (lc->balanceFactor == leftheavy)
|
||||
{
|
||||
// make a double rotation
|
||||
DoubleRotateLeft(p);
|
||||
// root is now balance
|
||||
reviseBalanceFactor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Tree::SingleRotateRight (TreeNode* &p)
|
||||
{
|
||||
// the left subtree of p is heavy
|
||||
TreeNode *lc;
|
||||
// the left subtree of p is heavy
|
||||
TreeNode *lc;
|
||||
|
||||
// assign the left subtree to lc
|
||||
lc = p->Left();
|
||||
// assign the left subtree to lc
|
||||
lc = p->Left();
|
||||
|
||||
// update the balance factor for parent and left child
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = balanced;
|
||||
// update the balance factor for parent and left child
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = balanced;
|
||||
|
||||
// any right subtree st of lc must continue as right
|
||||
// subtree of lc. do by making it a left subtree of p
|
||||
p->left = lc->Right();
|
||||
// any right subtree st of lc must continue as right
|
||||
// subtree of lc. do by making it a left subtree of p
|
||||
p->left = lc->Right();
|
||||
|
||||
// rotate p (larger node) into right subtree of lc
|
||||
// make lc the pivot node
|
||||
lc->right = p;
|
||||
p = lc;
|
||||
// rotate p (larger node) into right subtree of lc
|
||||
// make lc the pivot node
|
||||
lc->right = p;
|
||||
p = lc;
|
||||
}
|
||||
|
||||
void Tree::SingleRotateLeft (TreeNode* &p)
|
||||
{
|
||||
// the right subtree of p is heavy
|
||||
TreeNode *lc;
|
||||
// the right subtree of p is heavy
|
||||
TreeNode *lc;
|
||||
|
||||
// assign the left subtree to lc
|
||||
lc = p->Right();
|
||||
// assign the left subtree to lc
|
||||
lc = p->Right();
|
||||
|
||||
// update the balance factor for parent and left child
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = balanced;
|
||||
// update the balance factor for parent and left child
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = balanced;
|
||||
|
||||
// any right subtree st of lc must continue as right
|
||||
// subtree of lc. do by making it a left subtree of p
|
||||
p->right = lc->Left();
|
||||
// any right subtree st of lc must continue as right
|
||||
// subtree of lc. do by making it a left subtree of p
|
||||
p->right = lc->Left();
|
||||
|
||||
// rotate p (larger node) into right subtree of lc
|
||||
// make lc the pivot node
|
||||
lc->left = p;
|
||||
p = lc;
|
||||
// rotate p (larger node) into right subtree of lc
|
||||
// make lc the pivot node
|
||||
lc->left = p;
|
||||
p = lc;
|
||||
}
|
||||
|
||||
// double rotation right about node p
|
||||
void Tree::DoubleRotateRight (TreeNode* &p)
|
||||
{
|
||||
// two subtrees that are rotated
|
||||
TreeNode *lc, *np;
|
||||
// two subtrees that are rotated
|
||||
TreeNode *lc, *np;
|
||||
|
||||
// in the tree, node(lc) <= node(np) < node(p)
|
||||
lc = p->Left(); // lc is left child of parent
|
||||
np = lc->Right(); // np is right child of lc
|
||||
// in the tree, node(lc) <= node(np) < node(p)
|
||||
lc = p->Left(); // lc is left child of parent
|
||||
np = lc->Right(); // np is right child of lc
|
||||
|
||||
// update balance factors for p, lc, and np
|
||||
if (np->balanceFactor == rightheavy)
|
||||
{
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = rightheavy;
|
||||
}
|
||||
else if (np->balanceFactor == balanced)
|
||||
{
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = balanced;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->balanceFactor = rightheavy;
|
||||
lc->balanceFactor = balanced;
|
||||
}
|
||||
np->balanceFactor = balanced;
|
||||
// update balance factors for p, lc, and np
|
||||
if (np->balanceFactor == rightheavy)
|
||||
{
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = rightheavy;
|
||||
}
|
||||
else if (np->balanceFactor == balanced)
|
||||
{
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = balanced;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->balanceFactor = rightheavy;
|
||||
lc->balanceFactor = balanced;
|
||||
}
|
||||
np->balanceFactor = balanced;
|
||||
|
||||
// before np replaces the parent p, take care of subtrees
|
||||
// detach old children and attach new children
|
||||
lc->right = np->Left();
|
||||
np->left = lc;
|
||||
p->left = np->Right();
|
||||
np->right = p;
|
||||
p = np;
|
||||
// before np replaces the parent p, take care of subtrees
|
||||
// detach old children and attach new children
|
||||
lc->right = np->Left();
|
||||
np->left = lc;
|
||||
p->left = np->Right();
|
||||
np->right = p;
|
||||
p = np;
|
||||
}
|
||||
|
||||
void Tree::DoubleRotateLeft (TreeNode* &p)
|
||||
{
|
||||
// two subtrees that are rotated
|
||||
TreeNode *lc, *np;
|
||||
// two subtrees that are rotated
|
||||
TreeNode *lc, *np;
|
||||
|
||||
// in the tree, node(lc) <= node(np) < node(p)
|
||||
lc = p->Right(); // lc is right child of parent
|
||||
np = lc->Left(); // np is left child of lc
|
||||
// in the tree, node(lc) <= node(np) < node(p)
|
||||
lc = p->Right(); // lc is right child of parent
|
||||
np = lc->Left(); // np is left child of lc
|
||||
|
||||
// update balance factors for p, lc, and np
|
||||
if (np->balanceFactor == leftheavy)
|
||||
{
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = leftheavy;
|
||||
}
|
||||
else if (np->balanceFactor == balanced)
|
||||
{
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = balanced;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->balanceFactor = leftheavy;
|
||||
lc->balanceFactor = balanced;
|
||||
}
|
||||
np->balanceFactor = balanced;
|
||||
// update balance factors for p, lc, and np
|
||||
if (np->balanceFactor == leftheavy)
|
||||
{
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = leftheavy;
|
||||
}
|
||||
else if (np->balanceFactor == balanced)
|
||||
{
|
||||
p->balanceFactor = balanced;
|
||||
lc->balanceFactor = balanced;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->balanceFactor = leftheavy;
|
||||
lc->balanceFactor = balanced;
|
||||
}
|
||||
np->balanceFactor = balanced;
|
||||
|
||||
// before np replaces the parent p, take care of subtrees
|
||||
// detach old children and attach new children
|
||||
lc->left = np->Right();
|
||||
np->right = lc;
|
||||
p->right = np->Left();
|
||||
np->left = p;
|
||||
p = np;
|
||||
// before np replaces the parent p, take care of subtrees
|
||||
// detach old children and attach new children
|
||||
lc->left = np->Right();
|
||||
np->right = lc;
|
||||
p->right = np->Left();
|
||||
np->left = p;
|
||||
p = np;
|
||||
}
|
||||
|
||||
// if item is in the tree, delete it
|
||||
void Tree::Delete(const int& item)
|
||||
{
|
||||
// DNodePtr = pointer to node D that is deleted
|
||||
// PNodePtr = pointer to parent P of node D
|
||||
// RNodePtr = pointer to node R that replaces D
|
||||
TreeNode *DNodePtr, *PNodePtr, *RNodePtr;
|
||||
// DNodePtr = pointer to node D that is deleted
|
||||
// PNodePtr = pointer to parent P of node D
|
||||
// RNodePtr = pointer to node R that replaces D
|
||||
TreeNode *DNodePtr, *PNodePtr, *RNodePtr;
|
||||
|
||||
// search for a node containing data value item. obtain its
|
||||
// node address and that of its parent
|
||||
if ((DNodePtr = FindNode (item, PNodePtr)) == NULL)
|
||||
return;
|
||||
// search for a node containing data value item. obtain its
|
||||
// node address and that of its parent
|
||||
if ((DNodePtr = FindNode (item, PNodePtr)) == NULL)
|
||||
return;
|
||||
|
||||
// If D has NULL pointer, the
|
||||
// replacement node is the one on the other branch
|
||||
if (DNodePtr->right == NULL)
|
||||
RNodePtr = DNodePtr->left;
|
||||
else if (DNodePtr->left == NULL)
|
||||
RNodePtr = DNodePtr->right;
|
||||
// Both pointers of DNodePtr are non-NULL
|
||||
else
|
||||
{
|
||||
// Find and unlink replacement node for D
|
||||
// Starting on the left branch of node D,
|
||||
// find node whose data value is the largest of all
|
||||
// nodes whose values are less than the value in D
|
||||
// Unlink the node from the tree
|
||||
// If D has NULL pointer, the
|
||||
// replacement node is the one on the other branch
|
||||
if (DNodePtr->right == NULL)
|
||||
RNodePtr = DNodePtr->left;
|
||||
else if (DNodePtr->left == NULL)
|
||||
RNodePtr = DNodePtr->right;
|
||||
// Both pointers of DNodePtr are non-NULL
|
||||
else
|
||||
{
|
||||
// Find and unlink replacement node for D
|
||||
// Starting on the left branch of node D,
|
||||
// find node whose data value is the largest of all
|
||||
// nodes whose values are less than the value in D
|
||||
// Unlink the node from the tree
|
||||
|
||||
// PofRNodePtr = pointer to parent of replacement node
|
||||
TreeNode *PofRNodePtr = DNodePtr;
|
||||
// PofRNodePtr = pointer to parent of replacement node
|
||||
TreeNode *PofRNodePtr = DNodePtr;
|
||||
|
||||
// frist possible replacement is left child D
|
||||
RNodePtr = DNodePtr->left;
|
||||
// frist possible replacement is left child D
|
||||
RNodePtr = DNodePtr->left;
|
||||
|
||||
// descend down right subtree of the left child of D
|
||||
// keeping a record of current node and its parent.
|
||||
// when we stop, we have found the replacement
|
||||
while (RNodePtr->right != NULL)
|
||||
{
|
||||
PofRNodePtr = RNodePtr;
|
||||
RNodePtr = RNodePtr;
|
||||
}
|
||||
// descend down right subtree of the left child of D
|
||||
// keeping a record of current node and its parent.
|
||||
// when we stop, we have found the replacement
|
||||
while (RNodePtr->right != NULL)
|
||||
{
|
||||
PofRNodePtr = RNodePtr;
|
||||
RNodePtr = RNodePtr;
|
||||
}
|
||||
|
||||
if (PofRNodePtr == DNodePtr)
|
||||
// left child of deleted node is the replacement
|
||||
// assign right subtree of D to R
|
||||
RNodePtr->right = DNodePtr->right;
|
||||
else
|
||||
{
|
||||
// we moved at least one node down a right brance
|
||||
// delete replacement node from tree by assigning
|
||||
// its left branc to its parent
|
||||
PofRNodePtr->right = RNodePtr->left;
|
||||
if (PofRNodePtr == DNodePtr)
|
||||
// left child of deleted node is the replacement
|
||||
// assign right subtree of D to R
|
||||
RNodePtr->right = DNodePtr->right;
|
||||
else
|
||||
{
|
||||
// we moved at least one node down a right brance
|
||||
// delete replacement node from tree by assigning
|
||||
// its left branc to its parent
|
||||
PofRNodePtr->right = RNodePtr->left;
|
||||
|
||||
// put replacement node in place of DNodePtr.
|
||||
RNodePtr->left = DNodePtr->left;
|
||||
RNodePtr->right = DNodePtr->right;
|
||||
}
|
||||
}
|
||||
// put replacement node in place of DNodePtr.
|
||||
RNodePtr->left = DNodePtr->left;
|
||||
RNodePtr->right = DNodePtr->right;
|
||||
}
|
||||
}
|
||||
|
||||
// complete the link to the parent node
|
||||
// deleting the root node. assign new root
|
||||
if (PNodePtr == NULL)
|
||||
root = RNodePtr;
|
||||
// attach R to the correct branch of P
|
||||
else if (DNodePtr->data < PNodePtr->data)
|
||||
PNodePtr->left = RNodePtr;
|
||||
else
|
||||
PNodePtr->right = RNodePtr;
|
||||
// complete the link to the parent node
|
||||
// deleting the root node. assign new root
|
||||
if (PNodePtr == NULL)
|
||||
root = RNodePtr;
|
||||
// attach R to the correct branch of P
|
||||
else if (DNodePtr->data < PNodePtr->data)
|
||||
PNodePtr->left = RNodePtr;
|
||||
else
|
||||
PNodePtr->right = RNodePtr;
|
||||
|
||||
// delete the node from memory and decrement list size
|
||||
FreeTreeNode(DNodePtr); // this says FirstTreeNode in the book, should be a typo
|
||||
size--;
|
||||
// delete the node from memory and decrement list size
|
||||
FreeTreeNode(DNodePtr); // this says FirstTreeNode in the book, should be a typo
|
||||
size--;
|
||||
}
|
||||
|
||||
|
||||
@ -529,49 +529,49 @@ void Tree::Delete(const int& item)
|
||||
// assign node value to item; otherwise, insert item in tree
|
||||
void Tree::Update(const int& item)
|
||||
{
|
||||
if (current !=NULL && current->data == item)
|
||||
current->data = item;
|
||||
else
|
||||
Insert(item, item);
|
||||
if (current !=NULL && current->data == item)
|
||||
current->data = item;
|
||||
else
|
||||
Insert(item, item);
|
||||
}
|
||||
|
||||
// create duplicate of tree t; return the new root
|
||||
TreeNode *Tree::CopyTree(TreeNode *t)
|
||||
{
|
||||
// variable newnode points at each new node that is
|
||||
// created by a call to GetTreeNode and later attached to
|
||||
// the new tree. newlptr and newrptr point to the child of
|
||||
// newnode and are passed as parameters to GetTreeNode
|
||||
TreeNode *newlptr, *newrptr, *newnode;
|
||||
// variable newnode points at each new node that is
|
||||
// created by a call to GetTreeNode and later attached to
|
||||
// the new tree. newlptr and newrptr point to the child of
|
||||
// newnode and are passed as parameters to GetTreeNode
|
||||
TreeNode *newlptr, *newrptr, *newnode;
|
||||
|
||||
// stop the recursive scan when we arrive at an empty tree
|
||||
if (t == NULL)
|
||||
return NULL;
|
||||
// stop the recursive scan when we arrive at an empty tree
|
||||
if (t == NULL)
|
||||
return NULL;
|
||||
|
||||
// CopyTree builds a new tree by scanning the nodes of t.
|
||||
// At each node in t, CopyTree checks for a left child. if
|
||||
// present it makes a copy of left child or returns NULL.
|
||||
// the algorithm similarly checks for a right child.
|
||||
// CopyTree builds a copy of node using GetTreeNode and
|
||||
// appends copy of left and right children to node.
|
||||
// CopyTree builds a new tree by scanning the nodes of t.
|
||||
// At each node in t, CopyTree checks for a left child. if
|
||||
// present it makes a copy of left child or returns NULL.
|
||||
// the algorithm similarly checks for a right child.
|
||||
// CopyTree builds a copy of node using GetTreeNode and
|
||||
// appends copy of left and right children to node.
|
||||
|
||||
if (t->Left() !=NULL)
|
||||
newlptr = CopyTree(t->Left());
|
||||
else
|
||||
newlptr = NULL;
|
||||
if (t->Left() !=NULL)
|
||||
newlptr = CopyTree(t->Left());
|
||||
else
|
||||
newlptr = NULL;
|
||||
|
||||
if (t->Right() !=NULL)
|
||||
newrptr = CopyTree(t->Right());
|
||||
else
|
||||
newrptr = NULL;
|
||||
if (t->Right() !=NULL)
|
||||
newrptr = CopyTree(t->Right());
|
||||
else
|
||||
newrptr = NULL;
|
||||
|
||||
|
||||
// Build new tree from the bottom up by building the two
|
||||
// children and then building the parent
|
||||
newnode = GetTreeNode(t->data, newlptr, newrptr);
|
||||
// Build new tree from the bottom up by building the two
|
||||
// children and then building the parent
|
||||
newnode = GetTreeNode(t->data, newlptr, newrptr);
|
||||
|
||||
// return a pointer to the newly created node
|
||||
return newnode;
|
||||
// return a pointer to the newly created node
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
||||
@ -598,16 +598,16 @@ void Tree::DeleteTree(TreeNode *t)
|
||||
// set the root pointer back to NULL
|
||||
void Tree::ClearTree(TreeNode * &t)
|
||||
{
|
||||
DeleteTree(t);
|
||||
t = NULL; // root now NULL
|
||||
DeleteTree(t);
|
||||
t = NULL; // root now NULL
|
||||
}
|
||||
|
||||
// delete all nodes in list
|
||||
void Tree::ClearList(void)
|
||||
{
|
||||
delete root;
|
||||
delete current;
|
||||
size = 0;
|
||||
delete root;
|
||||
delete current;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -29,23 +29,23 @@ class TreeNode{
|
||||
|
||||
private:
|
||||
// points to the left and right children of the node
|
||||
TreeNode *left;
|
||||
TreeNode *right;
|
||||
TreeNode *left;
|
||||
TreeNode *right;
|
||||
|
||||
int balanceFactor;
|
||||
int data;
|
||||
void * aux_data;
|
||||
int balanceFactor;
|
||||
int data;
|
||||
void * aux_data;
|
||||
public:
|
||||
// make Tree a friend because it needs access to left and right pointer fields of a node
|
||||
friend class Tree;
|
||||
TreeNode * Left();
|
||||
TreeNode * Right();
|
||||
int GetData();
|
||||
void * GetAuxData() {return aux_data;};
|
||||
void SetAuxData(void * AuxData) {aux_data = AuxData;};
|
||||
int GetBalanceFactor();
|
||||
TreeNode(const int &item, TreeNode *lptr, TreeNode *rptr, int balfac = 0);
|
||||
//friend class DCASolver;
|
||||
// make Tree a friend because it needs access to left and right pointer fields of a node
|
||||
friend class Tree;
|
||||
TreeNode * Left();
|
||||
TreeNode * Right();
|
||||
int GetData();
|
||||
void * GetAuxData() {return aux_data;};
|
||||
void SetAuxData(void * AuxData) {aux_data = AuxData;};
|
||||
int GetBalanceFactor();
|
||||
TreeNode(const int &item, TreeNode *lptr, TreeNode *rptr, int balfac = 0);
|
||||
//friend class DCASolver;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
*_________________________________________________________________________*
|
||||
* POEMS: PARALLELIZABLE OPEN SOURCE EFFICIENT MULTIBODY SOFTWARE *
|
||||
* DESCRIPTION: SEE READ-ME *
|
||||
* FILE NAME: points.h *
|
||||
* FILE NAME: points.h *
|
||||
* AUTHORS: See Author List *
|
||||
* GRANTS: See Grants List *
|
||||
* COPYRIGHT: (C) 2005 by Authors as listed in Author's List *
|
||||
|
||||
@ -47,8 +47,8 @@
|
||||
class Joint;
|
||||
|
||||
class System{
|
||||
private:
|
||||
int * mappings;
|
||||
private:
|
||||
int * mappings;
|
||||
|
||||
public:
|
||||
double time;
|
||||
@ -61,7 +61,7 @@
|
||||
|
||||
int GetNumBodies();
|
||||
|
||||
int * GetMappings();
|
||||
int * GetMappings();
|
||||
|
||||
void AddBody(Body* body);
|
||||
|
||||
|
||||
@ -24,21 +24,21 @@
|
||||
|
||||
class VirtualColMatrix : public VirtualMatrix {
|
||||
public:
|
||||
VirtualColMatrix();
|
||||
~VirtualColMatrix();
|
||||
double& operator_2int (int i, int j); // array access
|
||||
double Get_2int (int i, int j) const;
|
||||
void Set_2int (int i, int j, double value);
|
||||
double BasicGet_2int(int i, int j) const;
|
||||
void BasicSet_2int(int i, int j, double value);
|
||||
void BasicIncrement_2int(int i, int j, double value);
|
||||
VirtualColMatrix();
|
||||
~VirtualColMatrix();
|
||||
double& operator_2int (int i, int j); // array access
|
||||
double Get_2int (int i, int j) const;
|
||||
void Set_2int (int i, int j, double value);
|
||||
double BasicGet_2int(int i, int j) const;
|
||||
void BasicSet_2int(int i, int j, double value);
|
||||
void BasicIncrement_2int(int i, int j, double value);
|
||||
|
||||
virtual double& operator_1int (int i) = 0; // array access
|
||||
virtual double Get_1int(int i) const = 0;
|
||||
virtual void Set_1int(int i, double value) = 0;
|
||||
virtual double BasicGet_1int(int i) const = 0;
|
||||
virtual void BasicSet_1int(int i, double value) = 0;
|
||||
virtual void BasicIncrement_1int(int i, double value) = 0;
|
||||
virtual double& operator_1int (int i) = 0; // array access
|
||||
virtual double Get_1int(int i) const = 0;
|
||||
virtual void Set_1int(int i, double value) = 0;
|
||||
virtual double BasicGet_1int(int i) const = 0;
|
||||
virtual void BasicSet_1int(int i, double value) = 0;
|
||||
virtual void BasicIncrement_1int(int i, double value) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -21,62 +21,62 @@
|
||||
#include <iostream>
|
||||
|
||||
enum MatrixType {
|
||||
MATRIX = 0,
|
||||
COLMATRIX = 1,
|
||||
ROWMATRIX = 2,
|
||||
MAT3X3 = 3,
|
||||
VECT3 = 4,
|
||||
MAT6X6 = 5,
|
||||
VECT6 = 6,
|
||||
COLMATMAP = 7,
|
||||
VECT4 = 8,
|
||||
MAT4X4 = 9
|
||||
MATRIX = 0,
|
||||
COLMATRIX = 1,
|
||||
ROWMATRIX = 2,
|
||||
MAT3X3 = 3,
|
||||
VECT3 = 4,
|
||||
MAT6X6 = 5,
|
||||
VECT6 = 6,
|
||||
COLMATMAP = 7,
|
||||
VECT4 = 8,
|
||||
MAT4X4 = 9
|
||||
};
|
||||
|
||||
class VirtualMatrix {
|
||||
protected:
|
||||
int numrows, numcols;
|
||||
int numrows, numcols;
|
||||
public:
|
||||
VirtualMatrix();
|
||||
virtual ~VirtualMatrix();
|
||||
int GetNumRows() const;
|
||||
int GetNumCols() const;
|
||||
VirtualMatrix();
|
||||
virtual ~VirtualMatrix();
|
||||
int GetNumRows() const;
|
||||
int GetNumCols() const;
|
||||
|
||||
double& operator() (int i, int j); // array access
|
||||
double Get(int i, int j) const;
|
||||
void Set(int i, int j, double value);
|
||||
double BasicGet(int i, int j) const;
|
||||
void BasicSet(int i, int j, double value);
|
||||
void BasicIncrement(int i, int j, double value);
|
||||
double& operator() (int i, int j); // array access
|
||||
double Get(int i, int j) const;
|
||||
void Set(int i, int j, double value);
|
||||
double BasicGet(int i, int j) const;
|
||||
void BasicSet(int i, int j, double value);
|
||||
void BasicIncrement(int i, int j, double value);
|
||||
|
||||
double& operator() (int i); // array access
|
||||
double Get(int i) const;
|
||||
void Set(int i, double value);
|
||||
double BasicGet(int i) const;
|
||||
void BasicSet(int i, double value);
|
||||
void BasicIncrement(int i, double value);
|
||||
double& operator() (int i); // array access
|
||||
double Get(int i) const;
|
||||
void Set(int i, double value);
|
||||
double BasicGet(int i) const;
|
||||
void BasicSet(int i, double value);
|
||||
void BasicIncrement(int i, double value);
|
||||
|
||||
virtual void Const(double value) = 0;
|
||||
virtual MatrixType GetType() const = 0;
|
||||
virtual void AssignVM(const VirtualMatrix& A) = 0;
|
||||
void Zeros();
|
||||
void Ones();
|
||||
virtual std::ostream& WriteData(std::ostream& c) const;
|
||||
virtual std::istream& ReadData(std::istream& c);
|
||||
virtual void Const(double value) = 0;
|
||||
virtual MatrixType GetType() const = 0;
|
||||
virtual void AssignVM(const VirtualMatrix& A) = 0;
|
||||
void Zeros();
|
||||
void Ones();
|
||||
virtual std::ostream& WriteData(std::ostream& c) const;
|
||||
virtual std::istream& ReadData(std::istream& c);
|
||||
|
||||
protected:
|
||||
virtual double& operator_2int(int i, int j) = 0;
|
||||
virtual double& operator_1int(int i);
|
||||
virtual double Get_2int(int i, int j) const = 0;
|
||||
virtual double Get_1int(int i) const ;
|
||||
virtual void Set_2int(int i, int j, double value) = 0;
|
||||
virtual void Set_1int(int i, double value);
|
||||
virtual double BasicGet_2int(int i, int j) const = 0;
|
||||
virtual double BasicGet_1int(int i) const ;
|
||||
virtual void BasicSet_2int(int i, int j, double value) = 0;
|
||||
virtual void BasicSet_1int(int i, double value);
|
||||
virtual void BasicIncrement_2int(int i, int j, double value) = 0;
|
||||
virtual void BasicIncrement_1int(int i, double value);
|
||||
virtual double& operator_2int(int i, int j) = 0;
|
||||
virtual double& operator_1int(int i);
|
||||
virtual double Get_2int(int i, int j) const = 0;
|
||||
virtual double Get_1int(int i) const ;
|
||||
virtual void Set_2int(int i, int j, double value) = 0;
|
||||
virtual void Set_1int(int i, double value);
|
||||
virtual double BasicGet_2int(int i, int j) const = 0;
|
||||
virtual double BasicGet_1int(int i) const ;
|
||||
virtual void BasicSet_2int(int i, int j, double value) = 0;
|
||||
virtual void BasicSet_1int(int i, double value);
|
||||
virtual void BasicIncrement_2int(int i, int j, double value) = 0;
|
||||
virtual void BasicIncrement_1int(int i, double value);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -32,15 +32,15 @@ class System;
|
||||
class Solver;
|
||||
|
||||
struct SysData{
|
||||
System * system;
|
||||
int solver;
|
||||
int integrator;
|
||||
System * system;
|
||||
int solver;
|
||||
int integrator;
|
||||
};
|
||||
|
||||
class Workspace {
|
||||
SysData * system; // the multibody systems data
|
||||
int currentIndex;
|
||||
int maxAlloc;
|
||||
SysData * system; // the multibody systems data
|
||||
int currentIndex;
|
||||
int maxAlloc;
|
||||
|
||||
public:
|
||||
Workspace();
|
||||
@ -50,7 +50,7 @@ public:
|
||||
double Tfull;
|
||||
double ConFac;
|
||||
double KE_val;
|
||||
int FirstTime;
|
||||
int FirstTime;
|
||||
|
||||
bool LoadFile(char* filename);
|
||||
|
||||
@ -69,20 +69,20 @@ public:
|
||||
bool MakeSystem(int& nbody, double *&masstotal, double **&inertia, double **&xcm, double **&vcm, double **&omega, double **&ex_space, double **&ey_space, double **&ez_space, int &njoint, int **&jointbody, double **&xjoint, int& nfree, int*freelist, double dthalf, double dtv, double tempcon, double KE);
|
||||
|
||||
|
||||
bool SaveSystem(int& nbody, double *&masstotal, double **&inertia, double **&xcm, double **&xjoint, double **&vcm, double **&omega, double **&ex_space, double **&ey_space, double **&ez_space, double **&acm, double **&alpha, double **&torque, double **&fcm, int **&jointbody, int &njoint);
|
||||
bool SaveSystem(int& nbody, double *&masstotal, double **&inertia, double **&xcm, double **&xjoint, double **&vcm, double **&omega, double **&ex_space, double **&ey_space, double **&ez_space, double **&acm, double **&alpha, double **&torque, double **&fcm, int **&jointbody, int &njoint);
|
||||
|
||||
bool MakeDegenerateSystem(int& nfree, int*freelist, double *&masstotal, double **&inertia, double **&xcm, double **&vcm, double **&omega, double **&ex_space, double **&ey_space, double **&ez_space);
|
||||
bool MakeDegenerateSystem(int& nfree, int*freelist, double *&masstotal, double **&inertia, double **&xcm, double **&vcm, double **&omega, double **&ex_space, double **&ey_space, double **&ez_space);
|
||||
int getNumberOfSystems();
|
||||
|
||||
void SetLammpsValues(double dtv, double dthalf, double tempcon);
|
||||
void SetKE(int temp, double SysKE);
|
||||
|
||||
void RKStep(double **&xcm, double **&vcm,double **&omega,double **&torque, double **&fcm, double **&ex_space, double **&ey_space, double **&ez_space);
|
||||
void RKStep(double **&xcm, double **&vcm,double **&omega,double **&torque, double **&fcm, double **&ex_space, double **&ey_space, double **&ez_space);
|
||||
|
||||
void WriteFile(char* filename);
|
||||
void WriteFile(char* filename);
|
||||
|
||||
private:
|
||||
void allocateNewSystem(); //helper function to handle vector resizing and such for the array of system pointers
|
||||
void allocateNewSystem(); //helper function to handle vector resizing and such for the array of system pointers
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user