A templated derived class based on SPnode. More...
Public Member Functions | |
virtual | ~MappedSPnode () |
Destructor. | |
MappedSPnode () | |
No-argument constructor. | |
MappedSPnode (const ivector &v) | |
Initialised constructor. | |
MappedSPnode (const LabBox &lb) | |
Initialised constructor. | |
MappedSPnode (const ivector &v, const T &r) | |
Initialised constructor. | |
MappedSPnode (const LabBox &lb, const T &r) | |
Initialised constructor. | |
MappedSPnode (const SPnode &other) | |
Copy constructor. | |
MappedSPnode (const MappedSPnode &other) | |
Copy constructor. | |
MappedSPnode< T > & | operator= (MappedSPnode< T > rhs) |
Copy assignment operator. | |
void | replaceMe (MappedSPnode< T > newNode) |
Replace the properties of this node and its descendents with the properties of another node and its descendents. | |
MappedSPnode< T > * | getParent () const |
Accessor for the parent of a node. | |
MappedSPnode< T > * | getLeftChild () const |
Accessor for the left child of a node. | |
MappedSPnode< T > * | getRightChild () const |
Accessor for the right child of a node. | |
T | getRange () const |
Accessor for the range. | |
void | setRange (T r) |
Set the range. | |
std::string | nodeStringSummary () const |
Get a string summary of this. | |
size_t | allocateRanges (const std::vector< T > &rangesToAllocate, size_t index=0) |
Recursively allocate a collection of ranges to this and children. | |
bool | splitToShape (std::string instruction) |
Splits paving according to string instruction. | |
virtual void | nodeExpand (int comp) |
Add two sibling nodes to this provided this is a leaf. | |
virtual void | nodeExpand () |
Add two sibling nodes to this provided this is a leaf. | |
T | range |
A range of type T. | |
virtual void | slice (const std::vector< int > &sliceDims, const std::vector< cxsc::real > &slicePts, const std::string &sliceFilename="") |
Slice this. | |
void | acceptSPExpandVisitor (const SPExpandVisitor< T > &visitor) |
Accept a SPExpandVisitor. | |
void | acceptSPValueVisitor (const SPValueVisitor< T > &visitor) |
Accept a SPValueVisitor visitor. | |
MappedSPnode< T > & | operator+= (const MappedSPnode< T > &add) |
Addition to self operator. | |
const MappedSPnode< T > | operator+ (const MappedSPnode< T > &add) const |
Addition operator. | |
MappedSPnode< T > & | operator+= (const T &add) |
Self-scalar addition operator. | |
const MappedSPnode< T > | operator+ (const T &add) const |
Scalar addition operator. | |
MappedSPnode< T > & | operator-= (const MappedSPnode< T > &sub) |
Subtraction from self operator. | |
const MappedSPnode< T > | operator- (const MappedSPnode< T > &sub) const |
Subtraction operator. | |
MappedSPnode< T > & | operator-= (const T &sub) |
Self-scalar subtraction operator. | |
const MappedSPnode< T > | operator- (const T &sub) const |
Scalar subtraction operator. | |
MappedSPnode< T > & | operator*= (const MappedSPnode< T > &mult) |
Multiplication of self operator. | |
const MappedSPnode< T > | operator* (const MappedSPnode< T > &mult) const |
Multiplication operator. | |
MappedSPnode< T > & | operator*= (const T &mult) |
Self-scalar multiplication operator. | |
const MappedSPnode< T > | operator* (const T &mult) const |
Scalar multiplication operator. | |
MappedSPnode< T > & | operator/= (const MappedSPnode< T > &div) |
Division of self operator. | |
const MappedSPnode< T > | operator/ (const MappedSPnode< T > &div) const |
Division operator. | |
MappedSPnode< T > & | operator/= (const T &div) |
Self-scalar division operator. | |
const MappedSPnode< T > | operator/ (const T &div) const |
Scalar division operator. | |
void | minimiseLeaves () |
Change this so that it has the minimum number of leaves necessary to represent the same overall 'shape' (combination of subpaving volumes and values) as before, by recombining any pair of sibling leaves with identical ranges so that their former parent becomes a leaf with the same range as formerly belonged to each child. | |
void | swapMSPSR (MappedSPnode &spn) |
Swap the properties of this and another. | |
virtual std::ostream & | nodePrint (std::ostream &os) const |
Print the details of a specific node in a subpaving. | |
virtual std::ostream & | leafOutputTabs (std::ostream &os) const |
Print the details of a single leaf node, using tab delimiters. | |
void | _reshapeTreesToUnion (MappedSPnode< T > *const rhs) |
Reshape this and so that both this and rhs have identical shapes after the operation and that shape is the non-minimal union of shape the of this shape and the shape of rhs before the operation. | |
virtual void | _addRanges (const MappedSPnode< T > *const other) |
Give this a range equal to range of this and range of other. | |
virtual void | _subtractRanges (const MappedSPnode< T > *const other) |
Give this a range equal to range of this - range of other. | |
virtual void | _multRanges (const MappedSPnode< T > *const other) |
Give this a range equal to range of this * range of other. | |
virtual void | _divRanges (const MappedSPnode< T > *const other) |
Give this a range equal to range of this divided by range of other. | |
virtual void | _addNonMinimalUnion (const MappedSPnode< T > &rhs) |
Make a non-minimal union of subpavings using addition of ranges. | |
virtual void | _subtractNonMinimalUnion (const MappedSPnode< T > &rhs) |
Make a non-minimal union of subpavings using subtraction of ranges. | |
virtual void | _multiplyNonMinimalUnion (const MappedSPnode< T > &rhs) |
Make a non-minimal union of subpavings using multiplication of ranges. | |
virtual void | _divideNonMinimalUnion (const MappedSPnode< T > &rhs) |
Make a non-minimal union of subpavings using division of ranges. | |
virtual void | _scalarAdd (const T &add) |
Increment range collection of this. | |
virtual void | _scalarSubtract (const T &sub) |
Increment range collection of this. | |
virtual void | _scalarMult (const T &mult) |
Scale up range of this. | |
virtual void | _scalarDiv (const T &div) |
Scale down range of this. | |
virtual void | _slice (const std::vector< int > &sliceDims, const std::vector< cxsc::real > &slicePts, unsigned randID=0) |
virtual void | _slice (const std::vector< int > &sliceDims, const std::vector< cxsc::real > &slicePts, const string &sliceFilename) |
virtual std::vector< cxsc::real > | sliceCheck (const std::vector< int > &sliceDims, const std::vector< cxsc::real > &slicePts) const |
Check slice parameters and return a full vector of slice points. | |
virtual std::ostream & | oneLineOutput (std::ostream &os, int level) const |
A templated derived class based on SPnode.
The base class SPnode is a node in the representation of a regular subpaving as a binary tree. A node represents a box (interval vector). SPnodes are linked together to form the tree. The initial box of the subpaving is the box represented by the root node of the tree. A box which has been split will be represented as node with one or two children. A subpaving of [x] (union of non-overlapping sub- boxes of [x]) is represented by the leaves (degenerate/ child-less) nodes in the tree.
The MappedSPnode template is parameterised on the type T of the range data mapped to (associated with) each node (i.e. with each element of the subpaving). Examples of range data types include reals, or intervals, or colours ...
A MappedSPnode node has a single value of type T mapped onto it. This value is referred to as the "range value" or "range".
This templatised class provides ways to perform some basic arithmetic-like operations on the subpaving and the data mapped to it.
It is probably best to regard this class as a class for non-minimal node-trees, ie a node either has two children or no children. The expand method will automatically make two children and there is no way of then creating a minimal tree by cutting off an 'unwanted' child. This means that the whole root paving is regarded as the 'support' of the mapping.
subpavings::MappedSPnode< T >::MappedSPnode | ( | const ivector & | v | ) | [inline, explicit] |
subpavings::MappedSPnode< T >::MappedSPnode | ( | const LabBox & | lb | ) | [inline, explicit] |
subpavings::MappedSPnode< T >::MappedSPnode | ( | const ivector & | v, |
const T & | r | ||
) | [inline] |
subpavings::MappedSPnode< T >::MappedSPnode | ( | const LabBox & | lb, |
const T & | r | ||
) | [inline] |
subpavings::MappedSPnode< T >::MappedSPnode | ( | const SPnode & | other | ) | [inline, explicit] |
Copy constructor.
Copies from a plain SPnode.
Copies from given node downwards.
: SPnode() { if (other.theBox != NULL) { theBox = new ivector( other.getBox() ); } nodeName = other.nodeName; //recursion on the children if (other.leftChild) { nodeAddLeft(new MappedSPnode( *(other.getLeftChild()))); } else leftChild=NULL; if (other.rightChild) { nodeAddRight(new MappedSPnode( *(other.getRightChild()))); } else rightChild=NULL; }
subpavings::MappedSPnode< T >::MappedSPnode | ( | const MappedSPnode< T > & | other | ) | [inline] |
Copy constructor.
Copies from a MappedSPnode.
Copies from given node downwards.
: SPnode() { if (other.theBox != NULL) { theBox = new ivector( other.getBox() ); } range = other.range; nodeName = other.nodeName; //recursion on the children if (other.leftChild) { nodeAddLeft(new MappedSPnode( *(other.getLeftChild()))); } else leftChild=NULL; if (other.rightChild) { nodeAddRight(new MappedSPnode( *(other.getRightChild()))); } else rightChild=NULL; }
virtual void subpavings::MappedSPnode< T >::_addRanges | ( | const MappedSPnode< T > *const | other | ) | [inline, protected, virtual] |
Give this a range equal to range of this and range of other.
Assumes that this and other are the same from leaves up to this and other, i.e. are roots of trees of the same shape up to the depth of this Note that other could be a taller trees than this: range collections are only combined up to the level of this.
{ if (other == NULL) { throw NullSubpavingPointer_Error( "MappedSPnode<T>::_addRanges(const MappedSPnode<T> * const)"); } // recurse on the children if any first if (!isLeaf()) { getLeftChild()->_addRanges( other->getLeftChild()); getRightChild()->_addRanges( other->getRightChild()); } // deal with this range collection range = range + other->range; }
virtual void subpavings::MappedSPnode< T >::_divideNonMinimalUnion | ( | const MappedSPnode< T > & | rhs | ) | [inline, protected, virtual] |
Make a non-minimal union of subpavings using division of ranges.
{ if ((isEmpty()) || rhs.isEmpty()) { throw IncompatibleDimensions_Error( "MappedSPnode<T>::_divideNonMinimalUnion(const MappedSPnode<T> * const)"); } // make copies of rhs to reshape MappedSPnode<T> rhsTemp(rhs); // reshape _reshapeTreesToUnion(&rhsTemp); _divRanges(&rhsTemp); }
virtual void subpavings::MappedSPnode< T >::_divRanges | ( | const MappedSPnode< T > *const | other | ) | [inline, protected, virtual] |
Give this a range equal to range of this divided by range of other.
Assumes that this and other are the same from leaves up to this and other, i.e. are roots of trees of the same shape up to the depth of this Note that other could be a taller trees than this: range collections are only combined up to the level of this.
{ if (other == NULL) { throw NullSubpavingPointer_Error( "MappedSPnode<T>::_divRanges(const MappedSPnode<T> * const)"); } // recurse on the children if any first if (!isLeaf()) { getLeftChild()->_divRanges( other->getLeftChild()); getRightChild()->_divRanges( other->getRightChild()); } // deal with this range collection range = range / other->range; }
virtual void subpavings::MappedSPnode< T >::_multiplyNonMinimalUnion | ( | const MappedSPnode< T > & | rhs | ) | [inline, protected, virtual] |
Make a non-minimal union of subpavings using multiplication of ranges.
{ // should not need to check on rhs not null here if ((isEmpty()) || rhs.isEmpty()) { throw IncompatibleDimensions_Error( "MappedSPnode<T>::_multiplyNonMinimalUnion(const MappedSPnode<T> * const)"); } // make copies of rhs to reshape MappedSPnode<T> rhsTemp(rhs); // reshape _reshapeTreesToUnion(&rhsTemp); _multRanges(&rhsTemp); }
virtual void subpavings::MappedSPnode< T >::_multRanges | ( | const MappedSPnode< T > *const | other | ) | [inline, protected, virtual] |
Give this a range equal to range of this * range of other.
Assumes that this and other are the same from leaves up to this and other, i.e. are roots of trees of the same shape up to the depth of this Note that other could be a taller trees than this: range collections are only combined up to the level of this.
{ if (other == NULL) { throw NullSubpavingPointer_Error( "MappedSPnode<T>::_multRanges(const MappedSPnode<T> * const)"); } // recurse on the children if any first if (!isLeaf()) { getLeftChild()->_multRanges( other->getLeftChild()); getRightChild()->_multRanges( other->getRightChild()); } // deal with this range collection range = range * other->range; }
virtual void subpavings::MappedSPnode< T >::_scalarAdd | ( | const T & | add | ) | [inline, protected, virtual] |
Increment range collection of this.
Increment range by type T scalar.
add | the scalar increment, of same type as range, to use. |
{ if (!isEmpty()) { range = range + add; // recurse on children if (hasLCwithBox()) getLeftChild()->_scalarAdd(add); if (hasRCwithBox()) getRightChild()->_scalarAdd(add); } }
virtual void subpavings::MappedSPnode< T >::_scalarDiv | ( | const T & | div | ) | [inline, protected, virtual] |
Scale down range of this.
Division this range by type T scalar.
div | the scalar divisor, of same type as range, to use. |
{ if (!isEmpty()) { range = range / div; // recurse on children if (hasLCwithBox()) getLeftChild()->_scalarDiv(div); if (hasRCwithBox()) getRightChild()->_scalarDiv(div); } }
virtual void subpavings::MappedSPnode< T >::_scalarMult | ( | const T & | mult | ) | [inline, protected, virtual] |
Scale up range of this.
Multiplication this range by type T scalar.
mult | the scalar multiplier, of same type as range, to use. |
{ if (!isEmpty()) { range = range * mult; // recurse on children if (hasLCwithBox()) getLeftChild()->_scalarMult(mult); if (hasRCwithBox()) getRightChild()->_scalarMult(mult); } }
virtual void subpavings::MappedSPnode< T >::_scalarSubtract | ( | const T & | sub | ) | [inline, protected, virtual] |
Increment range collection of this.
Increment range by type T scalar.
sub | the scalar decrement, of same type as range, to use. |
{ if (!isEmpty()) { range = range - sub; // recurse on children if (hasLCwithBox()) getLeftChild()->_scalarSubtract(sub); if (hasRCwithBox()) getRightChild()->_scalarSubtract(sub); } }
virtual void subpavings::MappedSPnode< T >::_subtractNonMinimalUnion | ( | const MappedSPnode< T > & | rhs | ) | [inline, protected, virtual] |
Make a non-minimal union of subpavings using subtraction of ranges.
{ // should not need to check on rhs not null here if ((isEmpty()) || rhs.isEmpty()) { throw IncompatibleDimensions_Error( "MappedSPnode<T>::_subtractNonMinimalUnion(const MappedSPnode<T> * const)"); } // make copies of rhs to reshape MappedSPnode<T> rhsTemp(rhs); // reshape _reshapeTreesToUnion(&rhsTemp); _subtractRanges(&rhsTemp); }
virtual void subpavings::MappedSPnode< T >::_subtractRanges | ( | const MappedSPnode< T > *const | other | ) | [inline, protected, virtual] |
Give this a range equal to range of this - range of other.
Assumes that this and other are the same from leaves up to this and other, i.e. are roots of trees of the same shape up to the depth of this Note that other could be a taller trees than this: range collections are only combined up to the level of this.
{ if (other == NULL) { throw NullSubpavingPointer_Error( "MappedSPnode<T>::_subtractRanges(const MappedSPnode<T> * const)"); } // recurse on the children if any first if (!isLeaf()) { getLeftChild()->_subtractRanges( other->getLeftChild()); getRightChild()->_subtractRanges( other->getRightChild()); } // deal with this range collection range = range - other->range; }
void subpavings::MappedSPnode< T >::acceptSPExpandVisitor | ( | const SPExpandVisitor< T > & | visitor | ) | [inline] |
Accept a SPExpandVisitor.
If this is a leaf, and if the node is willing to split, accepts the visitor and sets the range equal to the value returned by the visitor's visit operation, then recursively asks children to accept visitor too.
The node's willingness to split is based on the results of the isSplittableNode() method.
visitor | a visitor capable of expanding this according to its own criteria and also of returning a value to used as the range of this. |
{ #ifdef MYDEBUGVISITOR std::cout << "Using mappedspnode_sr expander accept" << std::endl; #endif // only accept the visit if this is a leaf and the node is splittable if (isLeaf() && isSplittableNode()) { range = visitor.visit(this); #ifdef MYDEBUGVISITOR std::cout << "after visit, range value = " << range << std::endl; #endif } #ifdef MYDEBUGVISITOR if (isLeaf() && !isSplittableNode()) { std::cout << "box is too small to split: volume is " << nodeRealVolume() << std::endl; } if(!isLeaf()) std::cout << "now visit children" << std::endl; #endif if (hasLCwithBox()) (getLeftChild())->acceptSPExpandVisitor(visitor); if (hasRCwithBox()) (getRightChild())->acceptSPExpandVisitor(visitor); }
void subpavings::MappedSPnode< T >::acceptSPValueVisitor | ( | const SPValueVisitor< T > & | visitor | ) | [inline] |
Accept a SPValueVisitor visitor.
Accepts the visitor and sets the range equal to the value returned by the vistor's visit operation.
Recursively asks children to accept visitor too.
visitor | a visitor capable of returning a value to be used as the range of this. |
{ #ifdef MYDEBUGVISITORE std::cout << "Using mappedspnode_sr valuer accept " << getNodeName() << std::endl; #endif range = visitor.visit(this); #ifdef MYDEBUGVISITORE std::cout << "after visit, range value = " << range << std::endl; #endif #ifdef MYDEBUGVISITORE if(!isLeaf()) std::cout << "now visit children" << std::endl; #endif if (hasLCwithBox()) (getLeftChild())->acceptSPValueVisitor(visitor); if (hasRCwithBox()) (getRightChild())->acceptSPValueVisitor(visitor); }
size_t subpavings::MappedSPnode< T >::allocateRanges | ( | const std::vector< T > & | rangesToAllocate, |
size_t | index = 0 |
||
) | [inline] |
Recursively allocate a collection of ranges to this and children.
Throws a std::invalid_argument if there are fewer values in rangesToAllocate than there are nodes in this.
Allocation order is this, left child with remainder of allocation, right child with remainder.
rangesToAllocate | a collection of range values to apply to the nodes of the tree rooted at this. |
index | is the index of the value in rangesToAllocate to become the value of the range for this. |
{ if (index >= rangesToAllocate.size()) { throw std::invalid_argument("Range allocations too short"); } range = rangesToAllocate[index]; std::size_t newIndex = index+1; if (hasLCwithBox()) { newIndex = getLeftChild()->allocateRanges(rangesToAllocate, newIndex); } if (hasRCwithBox()) { newIndex = getRightChild()->allocateRanges(rangesToAllocate, newIndex); } // have done all the children // if this is the root, want to check we have used all the allocations if (NULL == getParent()) { if (newIndex < rangesToAllocate.size()) { throw std::invalid_argument("More ranges than nodes in tree"); } } return newIndex; }
MappedSPnode<T>* subpavings::MappedSPnode< T >::getLeftChild | ( | ) | const [inline] |
Accessor for the left child of a node.
Reimplemented from subpavings::SPnode.
Reimplemented in subpavings::RealMappedSPnode, subpavings::BooleanValueMappedSPnode, and subpavings::IntervalMappedSPnode.
{ return (MappedSPnode<T>*) leftChild; }
MappedSPnode<T>* subpavings::MappedSPnode< T >::getParent | ( | ) | const [inline] |
Accessor for the parent of a node.
Reimplemented from subpavings::SPnode.
Reimplemented in subpavings::RealMappedSPnode, subpavings::BooleanValueMappedSPnode, and subpavings::IntervalMappedSPnode.
{ return (MappedSPnode<T>*) parent; }
T subpavings::MappedSPnode< T >::getRange | ( | ) | const [inline] |
Accessor for the range.
Reimplemented in subpavings::BooleanValueMappedSPnode.
{ return T(range); }
MappedSPnode<T>* subpavings::MappedSPnode< T >::getRightChild | ( | ) | const [inline] |
Accessor for the right child of a node.
Reimplemented from subpavings::SPnode.
Reimplemented in subpavings::RealMappedSPnode, subpavings::BooleanValueMappedSPnode, and subpavings::IntervalMappedSPnode.
{ return (MappedSPnode<T>*) rightChild; }
void subpavings::MappedSPnode< T >::minimiseLeaves | ( | ) | [inline] |
Change this so that it has the minimum number of leaves necessary to represent the same overall 'shape' (combination of subpaving volumes and values) as before, by recombining any pair of sibling leaves with identical ranges so that their former parent becomes a leaf with the same range as formerly belonged to each child.
Eg a node with two leafs where both children have the same value mapped to them can be represented as a single leaf with the value mapped to it. minimiseLeaves can be used after arithmetic operations on nodes to deal with cases where sibling leaf nodes in the result are equivalent in terms of their range values.
The minimisation process works from the leaves upwards, so that a tree could potentially be reduced to a single node if every pair of sibling leaves encountered in the process can be recombined.
{ if (!isLeaf()) { // can't do anything if this is a leaf // recurse first if ( hasLCwithBox() ) getLeftChild()->minimiseLeaves(); if ( hasRCwithBox() ) getRightChild()->minimiseLeaves(); // now do me if ( isSubLeaf() && (getLeftChild()->getRange() == getRightChild()->getRange()) ) { // make this range collection one of the childrens range = getLeftChild()->getRange(); delete leftChild; leftChild = NULL; delete rightChild; rightChild = NULL; } } }
virtual void subpavings::MappedSPnode< T >::nodeExpand | ( | int | comp | ) | [inline, virtual] |
Add two sibling nodes to this provided this is a leaf.
Creates two children each with half of the box of this. Split the box in half normal to dimension set by comp. comp argument is passed to Upper() and Lower()
comp | the dimension on which to bisect this to create children. |
Reimplemented from subpavings::SPnode.
Reimplemented in subpavings::IntervalMappedSPnode, subpavings::RealMappedSPnode, and subpavings::BooleanValueMappedSPnode.
{ // can only expand if there is a box if (isEmpty()) { throw NoBox_Error("MappedSPnode<T>::nodeExpand(int)"); } // only do something if this node is a leaf if (isLeaf()) { MappedSPnode<T>* newLC = NULL; MappedSPnode<T>* newRC = NULL; try { // ivectors to become boxes for new children ivector lC, rC; // Call Lower() and Upper() to put split boxes // into lC and rC respectively Lower(getBox(), lC, comp); Upper(getBox(), rC, comp); // make and add the new children newLC = new MappedSPnode<T>(lC, range); newRC = new MappedSPnode<T>(rC, range); nodeAddLeft(newLC); nodeAddRight(newRC); // both children get the same range as this //name the new children getLeftChild()->setNodeName(nodeName + "L"); getRightChild()->setNodeName(nodeName + "R"); // new children have range collection from this } catch(std::exception& e) { // overkill, but try to deal with all eventualities... try { if (getLeftChild() != NULL) { delete (getLeftChild()); leftChild = NULL; } if (getRightChild() != NULL) { delete (getRightChild()); rightChild = NULL; } if (newLC != NULL) { delete newLC; newLC = NULL; } if (newRC != NULL) { delete newRC; newRC = NULL; } } catch(std::exception& e) {} //catch and swallow throw; // rethrow original exception } } }
virtual void subpavings::MappedSPnode< T >::nodeExpand | ( | ) | [inline, virtual] |
Add two sibling nodes to this provided this is a leaf.
Creates two children each with half of the box of this.
Reimplemented from subpavings::SPnode.
Reimplemented in subpavings::IntervalMappedSPnode, subpavings::RealMappedSPnode, and subpavings::BooleanValueMappedSPnode.
{ int maxdiamcomp; // variable to hold first longest dimension double temp = ::MaxDiam(getBox(), maxdiamcomp); nodeExpand(maxdiamcomp); // complete nodeExpand }
virtual std::ostream& subpavings::MappedSPnode< T >::nodePrint | ( | std::ostream & | os | ) | const [inline, virtual] |
Print the details of a specific node in a subpaving.
Prints: nodeName [tab] "Box is" [tab] ... each interval in the box in cxsc output format ... [tab] "Box volume is" [tab] volume [tab] "range data is" [tab] range [newline]
os | the stream to print to. |
Reimplemented from subpavings::SPnode.
Reimplemented in subpavings::IntervalMappedSPnode, and subpavings::BooleanValueMappedSPnode.
{ // output for box in form: // box, volume, summary data if(theBox != NULL) { // do nothing if there is no box ivector thisBox = *theBox; // copy theBox os << nodeName << "\tBox is:\t"; for (int i = Lb(thisBox); i <= Ub(thisBox) ; i++) { // c-xsc default output for intervals os << "\t" << thisBox[i]; } os << "\tBox volume is:\t" << nodeVolume(); os << "\trange data:\t" << range << std::endl; } return os; }
std::string subpavings::MappedSPnode< T >::nodeStringSummary | ( | ) | const [inline, virtual] |
Get a string summary of this.
Used for debugging.
Reimplemented from subpavings::SPnode.
{ std::ostringstream oss; oss << "I am " << getNodeName() << "(address " << this << "),\n"; oss << "Dimension is " << getDimension() << ", address of box is " << theBox << "\n"; oss << "range is " << range << "\n"; oss << "my parent is "; if (getParent() != NULL) oss << getParent()->getNodeName(); else oss << "NULL"; oss << ", my left child is "; if (getLeftChild() != NULL) oss << getLeftChild()->getNodeName(); else oss << "NULL"; oss << ", my right child is "; if (getRightChild() != NULL) oss << getRightChild()->getNodeName(); else oss << "NULL"; return oss.str(); }
const MappedSPnode<T> subpavings::MappedSPnode< T >::operator* | ( | const MappedSPnode< T > & | mult | ) | const [inline] |
Multiplication operator.
mult | the object to multiply this by to give the object returned. |
{
MappedSPnode<T> result =(*this);
result*= mult;
return result;
}
const MappedSPnode<T> subpavings::MappedSPnode< T >::operator* | ( | const T & | mult | ) | const [inline] |
Scalar multiplication operator.
mult | the value to multiply this by to give the object returned. |
{
MappedSPnode<T> result =(*this);
result*= mult;
return result;
}
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator*= | ( | const MappedSPnode< T > & | mult | ) | [inline] |
Multiplication of self operator.
mult | the object to multiply this by. |
{ // if both empty, do nothing if (!isEmpty() || !mult.isEmpty()) { // just one empty or boxes don't match if ( isEmpty() || mult.isEmpty() || (getBox() != mult.getBox() ) ) { throw IncompatibleDimensions_Error( "MappedSPnode<T>::operator*=(const MappedSPnode<T>& const)"); } // both must be non-empty this->_multiplyNonMinimalUnion(mult); } return *this; }
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator*= | ( | const T & | mult | ) | [inline] |
Self-scalar multiplication operator.
mult | the value to multiply this by. |
{ _scalarMult(mult); return *this; }
const MappedSPnode<T> subpavings::MappedSPnode< T >::operator+ | ( | const MappedSPnode< T > & | add | ) | const [inline] |
Addition operator.
add | the object to add to this to give the object returned. |
{
MappedSPnode<T> result =(*this);
result+= add;
return result;
}
const MappedSPnode<T> subpavings::MappedSPnode< T >::operator+ | ( | const T & | add | ) | const [inline] |
Scalar addition operator.
add | the value to add to this to give the object returned. |
{
MappedSPnode<T> result =(*this);
result+= add;
return result;
}
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator+= | ( | const MappedSPnode< T > & | add | ) | [inline] |
Addition to self operator.
add | the object to add to this. |
{ // if both empty, do nothing if (!isEmpty() || !add.isEmpty()) { // just one empty or boxes don't match if ( isEmpty() || add.isEmpty() || (getBox() != add.getBox() ) ) { throw IncompatibleDimensions_Error( "MappedSPnode<T>::operator+=(const MappedSPnode<T>& const)"); } #ifdef LOGARITHMETIC int recordNumber = 0; std::string filename("MappedAddition"); this->_addNonMinimalUnionAdditionSpecial(add, filename, recordNumber); #else this->_addNonMinimalUnion(add); #endif } return *this; }
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator+= | ( | const T & | add | ) | [inline] |
Self-scalar addition operator.
add | the value to add to this. |
{ _scalarAdd(add); return *this; }
const MappedSPnode<T> subpavings::MappedSPnode< T >::operator- | ( | const MappedSPnode< T > & | sub | ) | const [inline] |
Subtraction operator.
sub | the object to subtract from this to give the object returned. |
{
MappedSPnode<T> result =(*this);
result-= sub;
return result;
}
const MappedSPnode<T> subpavings::MappedSPnode< T >::operator- | ( | const T & | sub | ) | const [inline] |
Scalar subtraction operator.
sub | the value to subtract from this to give the object returned. |
{
MappedSPnode<T> result =(*this);
result-= sub;
return result;
}
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator-= | ( | const MappedSPnode< T > & | sub | ) | [inline] |
Subtraction from self operator.
sub | the object to subtract from this. |
{ // if both empty, do nothing if (!isEmpty() || !sub.isEmpty()) { // just one empty or boxes don't match if ( isEmpty() || sub.isEmpty() || (getBox() != sub.getBox() ) ) { throw IncompatibleDimensions_Error( "MappedSPnode<T>::operator-=(const MappedSPnode<T>& const)"); } this->_subtractNonMinimalUnion(sub); } return *this; }
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator-= | ( | const T & | sub | ) | [inline] |
Self-scalar subtraction operator.
sub | the value to subtract from this. |
{ _scalarSubtract(sub); return *this; }
const MappedSPnode<T> subpavings::MappedSPnode< T >::operator/ | ( | const MappedSPnode< T > & | div | ) | const [inline] |
Division operator.
div | the object to divide this by to give the object returned. |
{
MappedSPnode<T> result =(*this);
result/= div;
return result;
}
const MappedSPnode<T> subpavings::MappedSPnode< T >::operator/ | ( | const T & | div | ) | const [inline] |
Scalar division operator.
div | the value to divide this by to give the object returned. |
{
MappedSPnode<T> result =(*this);
result/= div;
return result;
}
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator/= | ( | const MappedSPnode< T > & | div | ) | [inline] |
Division of self operator.
div | the object to divide this by. |
{ // if both empty, do nothing if (!isEmpty() || !div.isEmpty()) { // just one empty or boxes don't match if ( isEmpty() || div.isEmpty() || (getBox() != div.getBox() ) ) { throw IncompatibleDimensions_Error( "MappedSPnode<T>::operator/=(const MappedSPnode<T>& const)"); } // both must be non-empty this->_divideNonMinimalUnion(div); } return *this; }
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator/= | ( | const T & | div | ) | [inline] |
Self-scalar division operator.
div | the value to divide this by. |
{ _scalarDiv(div); return *this; }
MappedSPnode<T>& subpavings::MappedSPnode< T >::operator= | ( | MappedSPnode< T > | rhs | ) | [inline] |
Copy assignment operator.
Copies from given node downwards.
Reimplemented in subpavings::RealMappedSPnode, subpavings::BooleanValueMappedSPnode, and subpavings::IntervalMappedSPnode.
{ rhs.swapMSPSR(*this); // make sure we use our version of swap return(*this); }
void subpavings::MappedSPnode< T >::replaceMe | ( | MappedSPnode< T > | newNode | ) | [inline] |
Replace the properties of this node and its descendents with the properties of another node and its descendents.
Copies newNode node downwards into this, but keeps the relationship of this with its parent, ie if this is a node in a tree, the part of the tree rooted at this is made identical to newNode but the relationship to the rest of the tree,through the link between this and its parent, is retained.
Reimplemented in subpavings::RealMappedSPnode, subpavings::BooleanValueMappedSPnode, and subpavings::IntervalMappedSPnode.
void subpavings::MappedSPnode< T >::setRange | ( | T | r | ) | [inline] |
virtual void subpavings::MappedSPnode< T >::slice | ( | const std::vector< int > & | sliceDims, |
const std::vector< cxsc::real > & | slicePts, | ||
const std::string & | sliceFilename = "" |
||
) | [inline, virtual] |
Slice this.
Slice this on at the point jointly specified by sliceDims and slicePts. For example, if this has a 3-dimensional root box [-1,1]x[-1,1]x[-1,1], ie dimensions {1,2,3} and sliceDims = {2,3} and slicePts is (0.0,0.5) then we are slicing at point 0.0 on dimension 2, point 0.5 on dimension 3. After the opertation this would then have only one-dimensional boxes on dimensions {1,2,3}2,3} = {1}, each box being one that did contain point 0.0 on dimension 2, point 0.5 on dimension 3. The range will be unchanged). Any boxes associated with the original this that did not contain the point 0.0 on dimension 2 and 0.5 on dimension 3 will not be represented in its new form.
sliceDims | is a vector of dimensions to slice on, indexed from 1 onwards. |
slicePts | is a vector of points to slice on, assumed to correspond to the dimensions in sliceDims, ie the ith value in sliceDims gives the dimension for the ith point in slicePts. |
sliceFilename | is the name of file to use to capture the boxes of this that are used in the slice by outputting them to the file named sliceFilename. Defaults to the empty string "". If sliceFilename is the empty string "" no boxes will be captured to file. |
{ #ifdef SLICE_OUTPUT std::cout << "In MappedSPnode<T>::slice, I am " << getNodeName() << std::endl; #endif std::vector<cxsc::real> fullSlicePts = sliceCheck(sliceDims, slicePts); //start the file if (!sliceFilename.empty()) { std::ofstream os(sliceFilename.c_str()); if (os.is_open()) os.close(); } _slice(sliceDims, fullSlicePts, sliceFilename); }
virtual std::vector< cxsc::real > subpavings::MappedSPnode< T >::sliceCheck | ( | const std::vector< int > & | sliceDims, |
const std::vector< cxsc::real > & | slicePts | ||
) | const [inline, protected, virtual] |
Check slice parameters and return a full vector of slice points.
Checks that:
Throws exceptions if any problems are encountered.
sliceDims | is a vector of dimensions to slice on. |
slicePts | is a vector of points to slice on, assumed to correspond to the dimensions in sliceDims, ie the ith value in sliceDims gives the dimension for the ith point in slicePts. |
{ std::vector < cxsc::real > fullSlicePts; if ( getParent() != NULL ) { throw NonRootNode_Error( "sliceCheck error found"); } if ( !sliceDims.empty() || !slicePts.empty()) { if ( sliceDims.size() != slicePts.size()) { throw std::invalid_argument( "sliceCheck error found: sliceDims.size() != slicePts.size()"); } /* get ordered unique values in sliceDims*/ std::set<int> dimsSet(sliceDims.begin(), sliceDims.end()); if ( dimsSet.size() < sliceDims.size()) { throw std::invalid_argument( "sliceCheck error found: duplicate dimensions in sliceDims"); } if ( dimsSet.size() >= getDimension()) { throw std::invalid_argument( "sliceCheck error found: number of dimensions to slice on >= dimensions of this"); } /* check that each of the values in sliceDims is a dimension of this*/ ivector box = getBox(); int lb = Lb(box); int ub = Ub(box); // ub-lb+1 = dim of box // make a full vector of dim reals, 0.0's in all positions fullSlicePts = std::vector< cxsc::real >(ub-lb+1, real(0.0)); #ifdef SLICE_OUTPUT std::cout << "\nin slice" << getNodeName() << std::endl; std::cout << "lb = " << lb << " and ub = " << ub << std::endl; #endif std::vector < real >::const_iterator rit = slicePts.begin(); for ( std::vector < int >::const_iterator cit = sliceDims.begin(); cit < sliceDims.end(); ++cit, ++rit) { int d = *cit; #ifdef SLICE_OUTPUT std::cout << "checking d =" << d << std::endl; std::cout << "*rit =" << (*rit) << std::endl; #endif if (d < lb || d > ub) { throw std::invalid_argument( "sliceCheck error found: illegal dimension in sliceDims"); } #ifdef SLICE_OUTPUT std::cout << "box[d] =" << box[d] << std::endl; std::cout << "(*rit) <= box[d] =" << ((*rit) <= box[d]) << std::endl; #endif real r = *rit; if (!(r <= box[d])) { throw std::invalid_argument( "sliceCheck error found: illegal pt in slicePts"); } #ifdef SLICE_OUTPUT std::cout << "fullSlicePts[" << (d-lb) << "] = " << r << std::endl; #endif fullSlicePts[d-lb] = r; } } // end check at least one is non-empty else { // both empty throw std::invalid_argument( "sliceCheck error found: sliceDims and slicePts both empty"); } return fullSlicePts; }
bool subpavings::MappedSPnode< T >::splitToShape | ( | std::string | instruction | ) | [inline] |
Splits paving according to string instruction.
The instruction specifies the required shape in terms of the depth of the leaf nodes, in left to right order. The depth of a leaf node is equivalent to the number of bisections of the root box required to make the box represented by that leaf. i.e., the root has depth 0 and if that were bisected, the root node would have two child nodes each of level 1. Bisection of any one of the boxes represented by a child would give two more children, each of level 2 (2 bisections), etc.
Leaf levels in instruction can be separated by commas, spaces, or both.
For example, an instruction string "3, 3, 2, 1" would give an SPSnode tree with 4 leaves, 2 of which would be level 3 (i.e. representing boxes resulting from 3 bisections of the root box, each of which would have volume 1/8 the size of the root box). Another leaf would represent a box resulting from 2 bisections of the root box (volume 1/4 that of the root box) and the 'right-most' leaf (in a drawing of the tree) would be the result of a single bisection of the root box and would have half the volume of the root box. This is a valid instruction string because it is possible to get leaves of those levels by a series of successive bisections of the root box and the volume of the leaves adds up to the volume of the root box.
Throws the following exceptions:
instruction | specifies the required shape, eg "3, 3, 2, 1". |
{ bool success = false; // checks: is this the root? if (NULL != parent) { throw NonRootNode_Error("MappedSPNodeSingleRange<T>::splitToShape(std::string)"); } // checks: is there a root box if (NULL == theBox) { throw NoBox_Error("MappedSPNodeSingleRange<T>::splitToShape(std::string)"); } // checks: is the string properly formed? if (instruction.length() == 0) { throw std::invalid_argument( "MappedSPNodeSingleRange<T>::splitToShape(std::string) : No instruction"); } std::string legal(", 0123456789"); if (instruction.find_first_not_of(legal) != std::string::npos) { throw std::invalid_argument( "MappedSPNodeSingleRange<T>::splitToShape(std::string) : Illegal character"); } // all seems to be okay, we can start spliting the root // specify what to look for as numbers or decimal point or + or - success = splitRootToShape(instruction); if (!success) { throw std::logic_error( "MappedSPNodeSingleRange<T>::splitToShape(std::string) : instruction not a proper tree"); } return success; }
void subpavings::MappedSPnode< T >::swapMSPSR | ( | MappedSPnode< T > & | spn | ) | [inline] |
Swap the properties of this and another.
The properties swapped include all the node properties like name, box, etc, and children, and the range.
spn | the node to swap with. |
{ /* theBox, parent, leftChild, rightChild and nodeName are inherited from base class */ SPnode::swap(spn); // use the base version std::swap(range, spn.range); }