modifié : MakefileNoOTB

modifié :         include/ArrayTree/ArrayTreeBuilder.hpp
	modifié :         include/ArrayTree/ArrayTreeBuilder.tpp
	modifié :         include/ArrayTree/Border.hpp
	modifié :         include/ArrayTree/Border.tpp
	modifié :         include/ArrayTree/GraphWalker.hpp
	modifié :         include/ArrayTree/GraphWalker.tpp
	modifié :         include/ArrayTree/Leader.tpp
	modifié :         include/ArrayTree/triskeleArrayTreeBase.hpp
	modifié :         include/ArrayTree/triskeleArrayTreeBase.tpp
	modifié :         include/AttributeProfiles.hpp
	modifié :         include/AttributeProfiles.tpp
	modifié :         include/Attributes/AreaAttributes.hpp
	modifié :         include/Attributes/AverageAttributes.hpp
	modifié :         include/Attributes/MoIAttributes.hpp
	modifié :         include/Attributes/SDAttributes.hpp
	modifié :         include/Attributes/WeightAttributes.hpp
	modifié :         include/Attributes/XYAttributes.hpp
	modifié :         include/CompAttribute.hpp
	modifié :         include/CompAttribute.tpp
	modifié :         include/Tree.hpp
	modifié :         include/Tree.tpp
	modifié :         include/TreeStats.hpp
	modifié :         include/triskeleBase.hpp
	modifié :         include/triskeleBase.tpp
	modifié :         include/triskeleDebug.hpp
	modifié :         src/Tree.cpp
	modifié :         src/TreeStats.cpp
	modifié :         src/apGenerator.cpp
This commit is contained in:
Git Merciol 2018-03-06 19:56:25 +01:00
parent 22206596ad
commit 8149f1353b
29 changed files with 712 additions and 421 deletions

View File

@ -8,13 +8,17 @@ LIB_DIR = $(BLD_DIR)/lib
OBJ_DIR = $(BLD_DIR)/obj
## PRG #################################
TST_PRG = apGenerator
APG_PRG = apGenerator
APG_SRC = $(patsubst %, $(CPP_DIR)/%.cpp, $(APG_PRG))
APG_OUT = $(patsubst %, $(OUT_DIR)/%, $(APG_PRG))
TST_PRG = TestArrayTreeBuilder
TST_SRC = $(patsubst %, $(CPP_DIR)/%.cpp, $(TST_PRG))
TST_OUT = $(patsubst %, $(OUT_DIR)/%, $(TST_PRG))
## FLAGS ###############################
DFLAGS = -O2 -DNDEBUG -DBOOST_DISABLE_ASSERTS -DNO_OTB
#DFLAGS = -g -DENABLE_LOG -DNO_OTB # -DSMART_LOG # -DTHREAD_DISABLE
#DFLAGS = -g -DENABLE_LOG -DNO_OTB -DTHREAD_DISABLE -DENABLE_SMART_LOG
IFLAGS = $(DFLAGS) -MMD -I$(HPP_DIR)
LFLAGS = -L$(LIB_DIR) -ltriskele -lstdc++ -lpthread -lboost_system -lboost_chrono -lboost_thread -lboost_program_options -lboost_date_time -lboost_serialization -lboost_filesystem -lboost_unit_test_framework -lgdal
CC = g++
@ -31,7 +35,15 @@ $(OUT_DIR)/%: $(CPP_DIR)/*/%.cpp
$(CC) $(IFLAGS) $< -L$(LIB_DIR) $(LFLAGS) -cpp -o $@
## ENTRIES #############################
all: init libtriskele apGenerator
all: init libtriskele apGenerator test
testA: all
$(TST_OUT)
testB: all
# $(APG_OUT) data/nairobi-byte.tif data/result.tif -b 0 -w 4000 -h 4000 --min-tree -A data/areaThresholds.txt # --debug
# $(APG_OUT) data/10m.tif data/result.tif -b 0 --min-tree --max-tree --tos-tree -A data/areaThresholds.txt -S data/sdThresholds.txt -M data/moiThresholds.txt # --debug
$(APG_OUT) data/10m.tif data/result.tif --min-tree --max-tree --tos-tree -A data/areaThresholds.txt -S data/sdThresholds.txt -M data/moiThresholds.txt # --debug
init:
mkdir -p $(OUT_DIR) $(OBJ_DIR) $(LIB_DIR)
@ -40,19 +52,19 @@ clean:
wipe: clean
rm -rf $(OBJ_DIR)
rm -f $(TST_OUT) $(LIB_DIR)/libtriskele.a
rm -f $(APG_OUT) $(TST_OUT) $(LIB_DIR)/libtriskele.a
libtriskele: $(LIB_DIR)/libtriskele.a
$(APG_OUT): $(APG_SRC) $(LIB_DIR)/libtriskele.a
apGenerator: $(APG_OUT)
$(TST_OUT): $(TST_SRC) $(LIB_DIR)/libtriskele.a
apGenerator: $(TST_OUT)
# $(TST_OUT) data/nairobi-byte.tif data/result.tif -b 0 -w 4000 -h 4000 --min-tree -A data/areaThresholds.txt # --debug
# $(TST_OUT) data/10m.tif data/result.tif -b 0 --min-tree --max-tree --tos-tree -A data/areaThresholds.txt -S data/sdThresholds.txt -M data/moiThresholds.txt # --debug
$(TST_OUT) data/10m.tif data/result.tif --min-tree --max-tree --tos-tree -A data/areaThresholds.txt -S data/sdThresholds.txt -M data/moiThresholds.txt # --debug
test: $(TST_OUT)
## DEPENDS #############################
ALL_OUT = $(TST_OUT)
ALL_OUT = $(APG_OUT)
ALL_OBJ = $(OBJ_DIR)/IImage.o $(OBJ_DIR)/triskeleArrayTreeBase.o $(OBJ_DIR)/Tree.o $(OBJ_DIR)/triskeleDebug.o $(OBJ_DIR)/TreeStats.o $(OBJ_DIR)/triskeleBase.o $(OBJ_DIR)/QuadTreeBuilder.o $(OBJ_DIR)/Option.o $(OBJ_DIR)/Selected.o
ALL_OBJ_XML = $(OBJ_DIR)/IImage.o $(OBJ_DIR)/triskeleArrayTreeBase.o $(OBJ_DIR)/Tree.o $(OBJ_DIR)/triskeleDebug.o $(OBJ_DIR)/TreeStats.o $(OBJ_DIR)/triskeleBase.o $(OBJ_DIR)/QuadTreeBuilder.o $(OBJ_DIR)/XMLTreeBuilder.o $(OBJ_DIR)/Option.o $(OBJ_DIR)/Selected.o

View File

@ -7,6 +7,7 @@
#include <boost/chrono.hpp>
#include "triskeleBase.hpp"
#include "triskeleDebug.hpp"
#include "triskeleSort.hpp"
#include "triskeleDealThreads.hpp"
@ -51,10 +52,6 @@ namespace otb {
inline void
setAttributProfiles (AttributeProfiles<PixelT> &attributeProfiles, const WeightFunct &weightFunct);
// template<typename WeightFunct>
// inline void
// fillAPTree (PixelT *leafAPTree, const WeightFunct &weightFunct);
template<typename WeightFunct>
inline void
buildParents (Edge<WeightT> *edges, const WeightFunct &weightFunct, const Rect &tile, DimImg &topParent);
@ -63,9 +60,12 @@ namespace otb {
inline void
connectLeaf (DimImg a, DimImg b, const WeightT &weight, DimImg &parCount, const WeightFunct &weightFunct);
inline void
unlinkParent (const DimImg &par);
template<typename WeightFunct>
inline void
connectComp (DimImg newComp, DimImg topA, DimImg topB, const WeightFunct &weightFunct);
connect3Comp (DimImg newComp, DimImg topA, DimImg topB, const WeightFunct &weightFunct);
template<typename WeightFunct>
inline void
@ -81,7 +81,7 @@ namespace otb {
inline void
compress (const DimImg &compTop);
inline void
inline DimImg
createParent (DimImg &topParent, const WeightT &weight, DimImg &childA, DimImg &childB);
inline void
@ -107,19 +107,17 @@ namespace otb {
inline void
buildChildren ();
template<typename WeightFunct>
inline void
initWeights (const GraphWalker &graphWalker, const WeightFunct &weightFunct);
// #ifdef ENABLE_LOG
// inline void
// printTree (const Size &size, const bool &rec);
// inline void
// printLeaders (const Size &size);
// inline void
// printNewCompIdx (const Size &size);
// #endif
// nice ostream
struct CLogComp {
const ArrayTreeBuilder &atb;
const DimImg &compId;
inline CLogComp (const ArrayTreeBuilder &atb, const DimImg &compId);
inline ostream &print (ostream &out) const;
};
inline CLogComp logComp (const DimImg &compId) const { return CLogComp (*this, compId); }
friend inline ostream &operator << (ostream& out, const CLogComp &lc) { return lc.print (out); }
};
#include "ArrayTreeBuilder.tpp"

View File

@ -38,6 +38,7 @@ ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree, WeightAttributes<Weigh
childCountRec = childCount+2;
newCompId = leaders.getLeaders ();
compWeights = weightAttributes.getValues ();
SMART_LOG_EXPR (dealThreadFill_n (leafCount-1, coreCount, compWeights, 0));
auto start = high_resolution_clock::now ();
switch (treeType) {
@ -64,6 +65,8 @@ ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree, WeightAttributes<Weigh
newCompId = nullptr;
buildChildren ();
childCountRec = nullptr;
SMART_LOG (tree.printTree ());
}
// ========================================
@ -108,27 +111,31 @@ ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree, const WeightFunct &wei
unsigned int tileCount = tiles.size ();
unsigned int boundCount = boundaries.size ();
vector<DimImg> vertexMaxBounds;
vector<DimImg> edgesMaxBounds;
graphWalker.setMaxBounds (tiles, vertexMaxBounds, edgesMaxBounds);
vector<Edge<WeightT> *> tileEdges (tileCount);
vector<DimImg> compBases (tileCount);
vector<DimImg> compTops (tileCount);
DimImg compBase = 0;
Edge<WeightT> *edgeBase = &allEdges[0];
for (unsigned int i = 0; i < tileCount; ++i) {
tileEdges [i] = edgeBase;
Size zoneSize (tiles[i].width, tiles[i].height);
edgeBase += graphWalker.edgeMaxCount (zoneSize);
compBases [i] = compBase;
compTops [i] = compBase;
compBase += graphWalker.vertexMaxCount (zoneSize); /* -1, but prety LOG */
tileEdges [i] = &allEdges[edgesMaxBounds[i]];
compBases [i] = compTops [i] = vertexMaxBounds [i];
}
dealThreadRange (tileCount, coreCount, [this, &tileEdges, &weightFunct, &tiles, &compTops] (DimImg threadId) {
buildParents (tileEdges [threadId], weightFunct, tiles [threadId], compTops [threadId]);
});
SMART_LOG ("leaders:" << endl
<< printMap (leaders.getLeaders (), size, 0) << endl << endl
<< "compWeights:" << endl
<< printMap (compWeights, size, 0) << endl << endl
<< tree.printTree (2*leafCount-1));
// merge sub-tree
DimImg compCount = compTops [0];
DimImg *topC = NULL;
DimImg compBase = vertexMaxBounds[tileCount];
if (boundCount) {
vector<Edge<WeightT> *> edgeBounds (boundCount);
vector<DimImg> edgeCounts (boundCount);
@ -169,20 +176,32 @@ ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree, const WeightFunct &wei
});
}
SMART_LOG ("compWeights:" << endl
<< printMap (compWeights, size, 0) << endl << endl
<< tree.printTree (2*leafCount-1));
// compress
DimImg maxUsed = max (compTops[tileCount-1], topC != NULL ? *topC : 0);
dealThreadFill_n (maxUsed, coreCount, newCompId, DimImg_MAX);
SMART_LOG ("reuse leaders:" << endl
<< printMap (newCompId, size, 0) << endl << endl);
compCount = updateNewId (compBases, compTops, weightFunct);
compress (maxUsed);
SMART_LOG ("updateNewId:" << endl
<< printMap (newCompId, size, 0) << endl << endl);
compress (maxUsed);
SMART_LOG ("compress:" << endl
<< printMap (newCompId, size, 0) << endl << endl);
leaders.free ();
setNodeCount (tree, leafCount+compCount);
LOG ("nodeCount:" << tree.getNodeCount());
DimEdge root = compCount-1;
compParents[root] = root;
// DimEdge root = compCount-1;
// compParents[root] = root;
SMART_LOG ("compWeights:" << endl
<< printMap (compWeights, size, 0) << endl << endl);
}
// ========================================
@ -200,31 +219,13 @@ ArrayTreeBuilder<WeightT, PixelT>::setAttributProfiles (AttributeProfiles<PixelT
});
}
// ========================================
// template<typename WeightT, typename PixelT>
// template<typename WeightFunct>
// inline void
// ArrayTreeBuilder<WeightT, PixelT>::fillAPTree (PixelT *leafAPTree, const WeightFunct &weightFunct) {
// DEF_LOG ("ArrayTreeBuilder::fillLeafAPTree", "");
// dealThreadBound (leafCount, coreCount, [&weightFunct, &leafAPTree] (const DimImg &minVal, const DimImg &maxVal) {
// weightFunct.copyPixelsBound (leafAPTree, minVal, maxVal);
// });
// PixelT *compAPTree = leafAPTree+leafCount;
// dealThreadBound (getCompCount (), coreCount, [this, &weightFunct, &compAPTree] (const DimImg &minVal, const DimImg &maxVal) {
// weightFunct.weight2valueBound (compAPTree, compWeights, minVal, maxVal);
// });
// }
// ========================================
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT, PixelT>::buildParents (Edge<WeightT> *edges, const WeightFunct &weightFunct,
const Rect &tile, DimImg &topParent) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::buildParents", " tile:" << tile << " topParent:" << topParent << " counting:" << countingFlag);
#endif
const Rect &tile, DimImg &topParent) {
SMART_DEF_LOG ("ArrayTreeBuilder::buildParents", " tile:" << tile << " topParent:" << topParent << " counting:" << countingFlag);
DimEdge edgeCount = (sizeof (WeightT) < 3 || countingFlag) ?
graphWalker.getCountingSortedEdges<WeightT, WeightFunct> (tile, Surface, edges, weightFunct) :
graphWalker.getSortedEdges (tile, Surface, edges, weightFunct);
@ -247,9 +248,7 @@ ArrayTreeBuilder<WeightT, PixelT>::buildParents (Edge<WeightT> *edges, const Wei
BOOST_ASSERT (rb < leafCount || rb == DimImg_MAX);
// BOOST_ASSERT (ra == DimImg_MAX || compParents [ra] == DimImg_MAX);
// BOOST_ASSERT (rb == DimImg_MAX || compParents [rb] == DimImg_MAX);
#ifdef SMART_LOG
LOG (" w:" << curEdge.weight << " pa:" << pa << " pb:" << pb << " la:" << la << " lb:" << lb << " ra:" << ra << " rb:" << rb);
#endif
SMART_LOG (" w:" << curEdge.weight << " pa:" << pa << " pb:" << pb << " la:" << la << " lb:" << lb << " ra:" << ra << " rb:" << rb);
if (la == lb)
continue;
@ -277,7 +276,7 @@ ArrayTreeBuilder<WeightT, PixelT>::buildParents (Edge<WeightT> *edges, const Wei
} else if (ra == rb) {
// XXX
BOOST_ASSERT (false);
leader = lb;
continue;
} else if (compWeights[ra] == compWeights [rb]) {
// ra.weight = rb.weight // XXX ?= curEdge.weight
if (childCountRec [ra] < childCountRec [rb]) {
@ -303,140 +302,114 @@ ArrayTreeBuilder<WeightT, PixelT>::buildParents (Edge<WeightT> *edges, const Wei
leaders.link (pa, leader);
leaders.link (pb, leader);
#ifdef SMART_LOG
LOG (" leader:" << leader << " w:" << compWeights [leader] << " c:" << childCountRec [leader]);
#endif
SMART_LOG (" leader:" << leader << " w:" << compWeights [leader] << " c:" << childCountRec [leader]);
}
#ifdef SMART_LOG
LOG ("topParent:" << topParent);
#endif
SMART_LOG ("topParent:" << topParent);
}
// ========================================
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::unlinkParent (const DimImg &par) {
SMART_DEF_LOG ("ArrayTreeBuilder::unlinkParent", "par: " << logComp (par));
if (par == DimImg_MAX)
return;
BOOST_ASSERT (childCountRec [par]);
--childCountRec [par];
}
// ----------------------------------------
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT, PixelT>::connectLeaf (DimImg a, DimImg b, const WeightT &weight, DimImg &parCount, const WeightFunct &weightFunct) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::connectLeaf", "a:" << a << " b:" << b << " weight:" << weight);
#endif
SMART_DEF_LOG ("ArrayTreeBuilder::connectLeaf", "a:" << a << " b:" << b << " weight:" << weight);
BOOST_ASSERT (a < leafCount);
BOOST_ASSERT (b < leafCount);
BOOST_ASSERT (leafParents[a] < leafCount || leafParents[a] == DimImg_MAX);
BOOST_ASSERT (leafParents[b] < leafCount || leafParents[b] == DimImg_MAX);
DimImg parA = findTopComp (leafParents[a], weightFunct);
DimImg parB = findTopComp (leafParents[b], weightFunct);
if (parA == DimImg_MAX) {
swap (a, b);
swap (parA, parB);
}
if (parB == DimImg_MAX) {
// parA = parB = DimImg_MAX
createParent (parCount, weight, leafParents [a], leafParents [b]);
return;
}
if (parA == DimImg_MAX) {
// parA = DimImg_MAX & parB != DimImg_MAX
parB = findTopComp (parB, weight, weightFunct);
if (!weightFunct.isWeightInf (compWeights[parB], weight)) {
leafParents[a] = parB;
++childCountRec[parB];
return;
}
parA = findTopComp (compParents[parB], weightFunct);
DimImg parA = findTopComp (leafParents[a], weight, weightFunct);
DimImg parB = findTopComp (leafParents[b], weight, weightFunct);
SMART_LOG ("parA: " << logComp (parA) << " parB: " << logComp (parB));
// upW0 : no parent(s)
// Border case if parX == DimImg_MAX
if (parA == parB) {
if (parA == DimImg_MAX) {
createParent (parCount, weight, leafParents [a], compParents [parB]);
return;
SMART_LOG ("upW0: no parents");
createParent (parCount, weight, leafParents [a], leafParents [b]);
SMART_LOG ("createParent: " << logComp (leafParents[a]));
}
createParent (parCount, weight, leafParents [a], compParents [parB]);
compParents[leafParents [a]] = parA;
SMART_LOG ("same parents for: " << a << ", " << b);
return;
}
BOOST_ASSERT (parA < leafCount);
BOOST_ASSERT (parB < leafCount);
if (parA == parB)
return;
if (weightFunct.isWeightInf (compWeights[parA], compWeights[parB])) {
if (parA == DimImg_MAX) {
swap (a, b);
swap (parA, parB);
SMART_LOG ("swap: " << logComp (parA) << " " << logComp (parB));
}
if (weightFunct.isWeightInf (weight, compWeights[parB])) {
// 1
BOOST_ASSERT (weightFunct.isWeightInf (weight, compWeights[parA]));
--childCountRec [parA];
--childCountRec [parB];
#ifdef SMART_LOG
LOG ("connect leaf a:" << a << " b:" << b << " np:" << parCount << " (2)");
#endif
// XXX newParent = leafParents[a] => return ?
createParent (parCount, weight, leafParents [a], leafParents [b]);
connectComp (leafParents [a], parA, parB, weightFunct);
if ((parA == DimImg_MAX || weightFunct.isWeightInf (weight, compWeights[parA])) &&
weightFunct.isWeightInf (weight, compWeights[parB])) {
// upW1 & upW2 : upper
SMART_LOG ("upW1 | upW2: upper");
unlinkParent (parA);
unlinkParent (parB);
SMART_LOG ("parA: " << logComp (parA) << " parB: " << logComp (parB));
DimImg newComp = createParent (parCount, weight, leafParents [a], leafParents [b]);
SMART_LOG ("createParent: " << logComp (newComp));
connect3Comp (newComp, parA, parB, weightFunct);
return;
}
if (weightFunct.isWeightInf (weight, compWeights[parA])) {
// 2
--childCountRec [parA];
parB = findTopComp (parB, weight, weightFunct);
BOOST_ASSERT (parB < leafCount);
if (weight == compWeights[parB]) {
// 2a
++childCountRec[parB];
leafParents[a] = parB;
#ifdef SMART_LOG
LOG ("connect leaf a:" << a << " p:" << parB << " (" << childCountRec[parB] << ")");
#endif
connectComp (parA, parB, weightFunct);
if (parA != DimImg_MAX && weightFunct.isWeightInf (compWeights[parA], compWeights[parB])) {
swap (a, b);
swap (parA, parB);
SMART_LOG ("swap: " << logComp (parA) << " " << logComp (parB));
}
if (weightFunct.isWeightInf (compWeights[parB], weight) &&
(parA == DimImg_MAX ||
weightFunct.isWeightInf (compWeights[parA], weight) ||
weightFunct.isWeightInf (weight, compWeights[parA]))) {
// loW0 | loW1 | loW2 : lower
SMART_LOG ("loW0 | loW1 | loW2");
if (weightFunct.isWeightInf (compWeights[parA], weight)) {
swap (a, b);
swap (parA, parB);
SMART_LOG ("swap: " << logComp (parA) << " " << logComp (parB));
}
DimImg grandParB = findTopComp (compParents[parB], weightFunct);
unlinkParent (grandParB);
SMART_LOG ("grandParB: " << logComp (grandParB));
if (parA == DimImg_MAX || weightFunct.isWeightInf (weight, compWeights[parA])) {
// loW1 | loW2
SMART_LOG ("loW1 | loW2: lower");
unlinkParent (parA);
SMART_LOG ("parA: " << logComp (parA));
DimImg newComp = createParent (parCount, weight, leafParents [a], compParents [parB]);
SMART_LOG ("createParent: " << logComp (newComp));
connect3Comp (newComp, parA, grandParB, weightFunct);
return;
}
// 2b compWeights[parB] < weight
BOOST_ASSERT (weightFunct.isWeightInf (compWeights[parB], weight));
DimImg grandParB = findTopComp (compParents[parB], weightFunct);
--childCountRec [grandParB];
#ifdef SMART_LOG
LOG ("connect leaf a:" << a << " pb:" << parB << " np:" << parCount << " (2)");
#endif
// XXX newParent = leafParents[a] => return ?
createParent (parCount, weight, leafParents [a], compParents [parB]);
connectComp (leafParents [a], grandParB, parA, weightFunct);
return;
}
parA = findTopComp (parA, weight, weightFunct);
parB = findTopComp (parB, weight, weightFunct);
BOOST_ASSERT (parA < leafCount);
BOOST_ASSERT (parB < leafCount);
if (weightFunct.isWeightInf (compWeights[parA], compWeights[parB]))
swap (parA, parB);
if (weightFunct.isWeightInf (compWeights[parA], weight)) {
// 3
BOOST_ASSERT (!weightFunct.isWeightInf (weight, compWeights[parA]));
//BOOST_ASSERT (compParents[parA] < leafCount); // XXX pas sur !!!
//BOOST_ASSERT (compParents[parB] < leafCount); // XXX pas sur !!!
// loW0
SMART_LOG ("loW0: lower");
DimImg grandParA = findTopComp (compParents[parA], weightFunct);
DimImg grandParB = findTopComp (compParents[parB], weightFunct);
if (grandParA != DimImg_MAX)
--childCountRec [grandParA];
if (grandParB != DimImg_MAX)
--childCountRec [grandParB];
#ifdef SMART_LOG
LOG ("connect leaf pa:" << parA << " pb:" << parB << " np:" << parCount << " (2)");
#endif
// XXX newParent = compParents [parA] => return ?
createParent (parCount, weight, compParents [parA], compParents [parB]);
connectComp (compParents [parA], grandParA, grandParB, weightFunct);
unlinkParent (grandParA);
SMART_LOG ("grandParA: " << logComp (grandParA));
DimImg newComp = createParent (parCount, weight, compParents [parA], compParents [parB]);
SMART_LOG ("createParent: " << logComp (newComp));
connect3Comp (newComp, grandParA, grandParB, weightFunct);
return;
}
// 4
// eqW0 | eqW1 | eqW2 : no creation
if (parA == DimImg_MAX || weightFunct.isWeightInf (weight, compWeights[parA])) {
// eqW1 | eqW2
SMART_LOG ("eqW1 | eqW2: incr leaf");
unlinkParent (parA);
++childCountRec[parB];
leafParents[a] = parB;
SMART_LOG ("parA: " << logComp (parA) << " parB: " << logComp (parB));
}
// eqW0 | eqW1 | eqW2
SMART_LOG ("eqW0 | eqW1 | eqW2: connect");
connectComp (parA, parB, weightFunct);
}
@ -444,29 +417,22 @@ ArrayTreeBuilder<WeightT, PixelT>::connectLeaf (DimImg a, DimImg b, const Weight
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT, PixelT>::connectComp (DimImg newComp, DimImg topA, DimImg topB, const WeightFunct &weightFunct) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::connectComp", "newComp:" << newComp << " topA:" << topA << " topB:" << topB);
#endif
ArrayTreeBuilder<WeightT, PixelT>::connect3Comp (DimImg newComp, DimImg topA, DimImg topB, const WeightFunct &weightFunct) {
SMART_DEF_LOG ("ArrayTreeBuilder::connect3Comp", "newComp:" << newComp << " topA:" << topA << " topB:" << topB);
BOOST_ASSERT (newComp != DimImg_MAX);
if (topB == DimImg_MAX)
swap (topA, topB);
// XXX >>> test alpha
// if (topB == DimImg_MAX)
// return;
// XXX <<<
if (topB == DimImg_MAX)
return;
BOOST_ASSERT (topB != DimImg_MAX);
if (topA != DimImg_MAX && weightFunct.isWeightInf (compWeights[topA], compWeights[topB]))
swap (topA, topB);
BOOST_ASSERT (findTopComp (topB, weightFunct) == topB);
BOOST_ASSERT (weightFunct.isWeightInf (compWeights[newComp], compWeights[topB]));
compParents[newComp] = topB;
++childCountRec[topB];
#ifdef SMART_LOG
LOG ("connect comp nc:" << newComp << " tb:" << topB << " (" << childCountRec[topB] << ")");
#endif
SMART_LOG ("topB: " << logComp (topB));
connectComp (topA, topB, weightFunct);
}
@ -475,10 +441,7 @@ template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT, PixelT>::connectComp (DimImg topA, DimImg topB, const WeightFunct &weightFunct) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::connectComp", "topA:" << topA << " topB:" << topB);
#endif
SMART_DEF_LOG ("ArrayTreeBuilder::connectComp", "topA:" << topA << " topB:" << topB);
for (;;) {
if (topA == DimImg_MAX || topB == DimImg_MAX)
@ -490,37 +453,24 @@ ArrayTreeBuilder<WeightT, PixelT>::connectComp (DimImg topA, DimImg topB, const
topB = findTopComp (topB, compWeights[topA], weightFunct);
if (topA == topB)
return;
if (compWeights[topA] == compWeights[topB] &&
childCountRec[topA] < childCountRec[topB])
swap (topA, topB);
DimImg grandParB = findTopComp (compParents[topB], weightFunct);
if (compWeights[topA] == compWeights[topB]) {
if (childCountRec[topA] < childCountRec[topB])
swap (topA, topB);
DimImg parB = findTopComp (compParents[topB], weightFunct);
if (parB != DimImg_MAX)
--childCountRec[parB];
childCountRec [topA] += childCountRec[topB];
childCountRec[topA] += childCountRec[topB];
childCountRec[topB] = 0;
compParents[topB] = topA;
#ifdef SMART_LOG
LOG ("connect comp topB:" << topB << " topA:" << topA << " (" << childCountRec [topA] << ")");
#endif
topB = topA;
topA = findTopComp (parB, compWeights[topA], weightFunct);
continue;
}
DimImg parB = findTopComp (compParents[topB], weightFunct);
++childCountRec[topA];
} else
++childCountRec[topA];
compParents[topB] = topA;
#ifdef SMART_LOG
LOG ("connect comp topB:" << topB << " topA:" << topA << " (" << childCountRec [topA] << ")");
#endif
if (parB == DimImg_MAX)
SMART_LOG ("topA: " << logComp (topA) << " topB: " << logComp (topB));
if (grandParB == DimImg_MAX)
return;
--childCountRec[parB];
topB = findTopComp (topA, compWeights[parB], weightFunct);
topA = parB;
BOOST_ASSERT (childCountRec [grandParB]);
--childCountRec[grandParB];
SMART_LOG ("grandParB: " << logComp (grandParB));
topB = topA;
topA = findTopComp (grandParB, compWeights[topA], weightFunct);
}
}
@ -529,7 +479,7 @@ template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline DimImg
ArrayTreeBuilder<WeightT, PixelT>::updateNewId (const vector<DimImg> &compBases, const vector<DimImg> &compTops,
const WeightFunct &weightFunct) {
const WeightFunct &weightFunct) {
// DEF_LOG ("ArrayTreeBuilder::updateNewId", "");
DimImg compCount = compBases[0];
vector<DimImg> sizes (compBases.size ());
@ -553,6 +503,9 @@ ArrayTreeBuilder<WeightT, PixelT>::updateNewId (const DimImg curComp, DimImg &co
// top already set
return;
const DimImg &top = findCompMultiChild (curComp);
BOOST_ASSERT (top != DimImg_MAX);
BOOST_ASSERT (childCountRec[top]);
if (curComp != top) {
// 0 => merge || no more child
// 1 => unnecessary node
@ -592,9 +545,7 @@ template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::compress (const DimImg &compTop) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::compress", " compTop:" << compTop);
#endif
SMART_DEF_LOG ("ArrayTreeBuilder::compress", " compTop:" << compTop);
dealThreadRange (leafCount, coreCount, [this] (const DimImg &leaf) {
DimImg old = leafParents[leaf];
@ -616,9 +567,7 @@ ArrayTreeBuilder<WeightT, PixelT>::compress (const DimImg &compTop) {
continue;
}
#ifdef SMART_LOG
LOG ("comp curComp:" << curComp << " newIdxComp:" << newIdxComp);
#endif
SMART_LOG ("comp curComp:" << curComp << " newIdxComp:" << newIdxComp);
swap (compParents[curComp], compParents[newIdxComp]);
swap (compWeights[curComp], compWeights[newIdxComp]);
@ -630,12 +579,11 @@ ArrayTreeBuilder<WeightT, PixelT>::compress (const DimImg &compTop) {
// ========================================
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::createParent (DimImg &topParent, const WeightT &weight, DimImg &childA, DimImg &childB) {
inline DimImg
ArrayTreeBuilder<WeightT, PixelT>::createParent (DimImg &topParent, const WeightT &weight, DimImg &parentChildA, DimImg &parentChildB) {
childCountRec [topParent] = 2;
compWeights [topParent] = weight;
childA = childB = topParent;
++topParent;
return parentChildA = parentChildB = topParent++;
}
// ----------------------------------------
@ -651,6 +599,7 @@ template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::addChildren (const DimImg &parent, const DimImg &sibling) {
childCountRec [parent] += childCountRec [sibling];
childCountRec [sibling] = 0;
compParents [sibling] = parent;
}
@ -686,6 +635,10 @@ template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline DimImg
ArrayTreeBuilder<WeightT, PixelT>::findTopComp (DimImg comp, const WeightT &weight, const WeightFunct &weightFunct) {
if (comp == DimImg_MAX)
return DimImg_MAX;
if (weightFunct.isWeightInf (weight, compWeights [comp]))
return findTopComp (comp, compWeights [comp], weightFunct);
DimImg last = comp;
for (;;) {
if (comp == DimImg_MAX)
@ -719,9 +672,7 @@ template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::buildChildren () {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::buildChildren", "");
#endif
SMART_DEF_LOG ("ArrayTreeBuilder::buildChildren", "");
BOOST_ASSERT (childCount[0] == 0);
BOOST_ASSERT (childCount[1] == 0);
@ -740,48 +691,31 @@ ArrayTreeBuilder<WeightT, PixelT>::buildChildren () {
BOOST_ASSERT (childCount[0] == 0);
}
// ----------------------------------------
// ========================================
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT, PixelT>::initWeights (const GraphWalker &graphWalker, const WeightFunct &weightFunct) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::initCompWeights", "leafCount:" << leafCount);
dealThreadFill_n (leafCount, coreCount, compWeights, 0);
#endif
// graphWalker.forEachVertexIdx ([this, &weightFunct] (const DimImg &compIdx){
// mapWeights[compIdx] = weightFunct.getWeight (compIdx);
// });
ArrayTreeBuilder<WeightT, PixelT>::CLogComp::CLogComp (const ArrayTreeBuilder &atb, const DimImg &compId)
: atb (atb), compId (compId) {
}
template<typename WeightT, typename PixelT>
inline ostream &
ArrayTreeBuilder<WeightT, PixelT>::CLogComp::print (ostream &out) const {
if (compId == DimImg_MAX)
return out << "M(-/-)";
return out << compId << "(" << atb.childCountRec[compId] << "/" << atb.compWeights [compId] << ")";
}
// ========================================
// #ifdef ENABLE_LOG
// template<typename WeightT, typename PixelT>
// inline void
// ArrayTreeBuilder<WeightT, PixelT>::printTree (const Size &size, const bool &rec) {
// cout << "tree weight parent " << (rec ? "countRec" : "count children") << endl;
// Size doubleSize (size.width, 2*size.height);
// triskele::printMap (cout, compWeights, size, (DimNodeId) getCompCount ()) << endl;
// triskele::printMap (cout, leafParents, doubleSize) << endl;
// triskele::printMap (cout, rec ? childCountRec : childCount, size) << endl;
// if (!rec)
// printMap (cout, children, doubleSize, nodeCount) << endl << endl;
// inline ArrayTreeBuilder<WeightT, PixelT>::CLogComp
// ArrayTreeBuilder<WeightT, PixelT>::logComp (const DimImg &compId) const {
// return ArrayTreeBuilder<WeightT, PixelT>::CLogComp (*this, compId);
// }
// template<typename WeightT, typename PixelT>
// inline void
// ArrayTreeBuilder<WeightT, PixelT>::printLeaders (const Size &size) {
// cout << "leaders" << endl;
// triskele::printMap (cout, newCompId, size) << endl;
// }
// template<typename WeightT, typename PixelT>
// inline void
// ArrayTreeBuilder<WeightT, PixelT>::printNewCompId (const Size &size) {
// cout << "newCompId" << endl;
// triskele::printMap (cout, newCompId, size) << endl;
// }
// #endif
// template<typename WeightT, typename PixelT>
// inline ostream&
// operator << (ostream& out, const ArrayTreeBuilder<WeightT, PixelT>::CLogComp &lc) {
// return lc.print (out);
// }
// ========================================
#endif // _OTB_TRISKELE_ARRAY_TREE_BUILDER_TPP

View File

@ -61,6 +61,8 @@ namespace otb {
/*! Tableau "simplifié" des pixels */
uint8_t *map;
friend inline ostream &operator << (ostream &out, const Border &border);
};
#include "Border.tpp"

View File

@ -79,4 +79,16 @@ Border::borderCount () {
return result;
}
inline ostream &operator << (ostream &out, const Border &border) {
if (border.size.width > printMapMaxSide || border.size.height > printMapMaxSide) {
return out << "map too big to print!" << std::endl;
}
for (DimSideImg y = 0, idx = 0; y < border.size.height; ++y) {
for (DimSideImg x = 0; x < border.size.width; ++x, ++idx)
out << (border.isBorder (idx) ? " B " : " - ");
out << endl;
}
return out;
}
#endif // _OTB_TRISKELE_ARRAY_TREE_BORDER_HPP

View File

@ -24,6 +24,7 @@ namespace otb {
namespace arrayTree {
using namespace ::triskele;
using namespace std;
/** GraphWalker */
class GraphWalker {
@ -40,7 +41,8 @@ namespace otb {
inline DimEdge edgeBoundaryMaxCount (const DimSideImg &side) const;
inline void setTiles (const unsigned int &coreCount, const Rect &tile,
std::vector<Rect> &tiles, std::vector<Rect> &boundaries, std::vector<bool> &verticalBoundaries) const;
vector<Rect> &tiles, vector<Rect> &boundaries, vector<bool> &verticalBoundaries) const;
inline void setMaxBounds (const vector<Rect> &tiles, vector<DimImg> &vertexMaxBounds, vector<DimImg> &edgesMaxBounds) const;
template<typename Funct>
inline DimImg forEachVertexIdx (const Funct &lambda /*lambda (idx)*/) const;

View File

@ -65,7 +65,7 @@ GraphWalker::edgeBoundaryMaxCount (const DimSideImg &side) const {
// ========================================
inline void
GraphWalker::setTiles (const unsigned int &coreCount, const Rect &tile,
std::vector<Rect> &tiles, std::vector<Rect> &boundaries, std::vector<bool> &verticalBoundaries) const {
vector<Rect> &tiles, vector<Rect> &boundaries, vector<bool> &verticalBoundaries) const {
BOOST_ASSERT (coreCount);
DEF_LOG ("GraphWalker::setTiles", "coreCount:" << coreCount << " tile:" << tile);
if (coreCount < 2 || max (tile.width, tile.height) < 4 || min (tile.width, tile.height) < 3) {
@ -93,10 +93,24 @@ GraphWalker::setTiles (const unsigned int &coreCount, const Rect &tile,
setTiles ((odd ? coreCount-1 : coreCount/2), tileB, tiles, boundaries, verticalBoundaries);
}
inline void
GraphWalker::setMaxBounds (const vector<Rect> &tiles, vector<DimImg> &vertexMaxBounds, vector<DimImg> &edgesMaxBounds) const {
unsigned int tileCount = tiles.size ();
vertexMaxBounds.resize (tileCount+1);
edgesMaxBounds.resize (tileCount+1);
DimImg vertexBase = 0, edgesBase = 0;
vertexMaxBounds [0] = edgesMaxBounds [0] = 0;
for (unsigned int i = 0; i < tileCount; ++i) {
Size zoneSize (tiles[i].width, tiles[i].height);
vertexMaxBounds [i+1] = vertexBase += vertexMaxCount (zoneSize); /* -1, but prety LOG */
edgesMaxBounds [i+1] = edgesBase += edgeMaxCount (zoneSize);
}
}
// ========================================
template<typename Funct>
inline DimImg
GraphWalker::forEachVertexIdx (const Funct &lambda /*lambda (idx)*/) const {
GraphWalker::forEachVertexIdx (const Funct &lambda /*lambda (DimImg idx)*/) const {
DimImg maxCount = vertexMaxCount ();
DimImg vertexCount = 0;
for (DimImg idx = 0; idx < maxCount; ++idx)
@ -106,7 +120,7 @@ GraphWalker::forEachVertexIdx (const Funct &lambda /*lambda (idx)*/) const {
template<typename Funct>
inline DimImg
GraphWalker::forEachVertexIdx (const Rect &rect, const Funct &lambda /*lambda (idx)*/) const {
GraphWalker::forEachVertexIdx (const Rect &rect, const Funct &lambda /*lambda (DimImg idx)*/) const {
DimImg vertexCount = 0;
DimSideImg const lastX = rect.x+rect.width;
DimSideImg const lastY = rect.y+rect.height;
@ -121,7 +135,7 @@ GraphWalker::forEachVertexIdx (const Rect &rect, const Funct &lambda /*lambda (i
template<typename Funct>
inline DimImg
GraphWalker::forEachVertexPt (const Rect &rect, const Funct &lambda /*lambda (p)*/) const {
GraphWalker::forEachVertexPt (const Rect &rect, const Funct &lambda /*lambda (Point p)*/) const {
DimImg vertexCount = 0;
DimSideImg const lastX = rect.x+rect.width;
DimSideImg const lastY = rect.y+rect.height;
@ -137,7 +151,7 @@ GraphWalker::forEachVertexPt (const Rect &rect, const Funct &lambda /*lambda (p)
// ========================================
template<typename Funct>
inline DimEdge
GraphWalker::forEachEdgePt (const Rect &rect, TileItem tileItem, const Funct &lambda /*lambda (p0, p1)*/) const {
GraphWalker::forEachEdgePt (const Rect &rect, TileItem tileItem, const Funct &lambda /*lambda (Point p0, Point p1)*/) const {
DimImg edgeCount = 0;
if (!rect.width || !rect.height)
return edgeCount;
@ -228,12 +242,12 @@ GraphWalker::getMedian (const EdgeWeightFunction &ef /*ef.getValue (idx)*/) cons
int bits = 8*sizeof (WeightT);
BOOST_ASSERT (bits < 17);
DimEdge dim = 1UL << bits;
std::vector<DimImg> indices (dim+1, 0);
vector<DimImg> indices (dim+1, 0);
DimImg *histogram = &indices[1];
forEachVertexIdx ([&histogram, &ef] (const DimImg &idx) {
++histogram[(size_t) ef.getValue (idx)];
});
std::partial_sum (histogram, histogram+dim, histogram);
partial_sum (histogram, histogram+dim, histogram);
return lower_bound (indices.begin (), indices.end (), indices[dim] >> 1) - indices.begin ();
}
@ -259,8 +273,11 @@ GraphWalker::getEdges (const Rect &rect, TileItem tileItem, Edge<WeightT> *edges
template <typename WeightT, typename EdgeWeightFunction>
inline DimEdge
GraphWalker::getSortedEdges (const Rect &rect, TileItem tileItem, Edge<WeightT> *edges, const EdgeWeightFunction &ef /*ef.getWeight (p0, p1) ef.sort ()*/) const {
SMART_DEF_LOG ("GraphWalker::getSortedEdges", "");
DimEdge edgeCount = getEdges (rect, tileItem, edges, ef);
// SMART_LOG (endl << printEdges (edges, size, edgeCount));
ef.sort (edges, edgeCount);
SMART_LOG (endl << printEdges (edges, size, edgeCount))
return edgeCount;
}
@ -268,20 +285,21 @@ template <typename WeightT, typename EdgeWeightFunction>
// template DimImg
inline DimEdge
GraphWalker::getCountingSortedEdges (const Rect &rect, TileItem tileItem, Edge<WeightT> *edges, const EdgeWeightFunction &ef /*ef.getWeight (p0, p1)*/) const {
SMART_DEF_LOG ("GraphWalker::getCountingSortedEdges", "");
int bits = 8*sizeof (WeightT);
BOOST_ASSERT (bits < 17);
DimEdge dim = 1UL << bits;
DimImg *indices = new DimImg [dim+1];
DimImg *histogram = indices+1;
DimImg sum = 0;
::std::fill_n (histogram, dim, 0);
fill_n (histogram, dim, 0);
forEachEdgePt (rect, tileItem,
[&histogram, &ef] (Point const &a, Point const &b) {
++histogram[(size_t) ef.getWeight (a, b)];
});
// get indices by prefix sum
std::partial_sum (histogram, histogram+dim, histogram);
partial_sum (histogram, histogram+dim, histogram);
sum = indices[dim];
if (ef.getDecr ()) {
for (size_t i = 0; i < dim; ++i)
@ -292,7 +310,7 @@ GraphWalker::getCountingSortedEdges (const Rect &rect, TileItem tileItem, Edge<W
// extract edges
forEachEdgePt (rect, tileItem,
[
#ifdef SMART_LOG
#ifdef ENABLE_SMART_LOG
this,
#endif
&ef, &edges, &indices] (Point const &a, Point const &b) {
@ -301,15 +319,9 @@ GraphWalker::getCountingSortedEdges (const Rect &rect, TileItem tileItem, Edge<W
edge.points[0] = a;
edge.points[1] = b;
edge.weight = weight;
#ifdef SMART_LOG
printEdge (cerr, edge, size) << endl;
#endif
SMART_LOG_EXPR (cerr << printEdge (edge, size) << endl);
});
#ifdef SMART_LOG
cerr << endl;
for (int i = 0; i < sum; ++i)
printEdge (cerr, edges[i], size) << endl;
#endif
SMART_LOG (endl << printEdges (edges, size, sum));
delete [] (histogram-1);
return sum;
}

View File

@ -16,9 +16,7 @@ Leader::~Leader () {
// ========================================
inline void
Leader::book (DimImg vertexCount) {
#ifdef SMART_LOG
DEF_LOG ("Leader::book", "vertexCount:" << vertexCount);
#endif
SMART_DEF_LOG ("Leader::book", "vertexCount:" << vertexCount);
if (vertexCount == size) {
reset ();
return;
@ -34,9 +32,7 @@ Leader::book (DimImg vertexCount) {
// ---------------------------------------
inline void
Leader::free () {
#ifdef SMART_LOG
DEF_LOG ("Leader::free", "");
#endif
SMART_DEF_LOG ("Leader::free", "");
if (leaders)
delete [] leaders;
leaders = NULL;

View File

@ -15,6 +15,7 @@ namespace otb {
class GraphWalker;
using namespace ::triskele;
using namespace std;
/*! Nombre de voisins */
typedef uint32_t DimEdge; // ~4*nbPixels (8-connectivity)
@ -29,23 +30,23 @@ namespace otb {
enum TreeType { MIN, MAX, TOS, ALPHA, TreeTypeCard};
/*! Définit les noms des connectivités (utile pour le debug) */
extern std::string connectivityName[];
extern string connectivityName[];
/*! Définit les noms des tileItem (utile pour le debug) */
extern std::string tileItemName[];
extern string tileItemName[];
/*! Définit les noms des arbres (utile pour le debug) */
extern std::string treeTypeLabels[];
extern string treeTypeLabels[];
/*!
* Opérateur de flux sur les connectivités
*/
inline std::ostream &operator << (std::ostream &out, const Connectivity &c);
inline ostream &operator << (ostream &out, const Connectivity &c);
/*!
* Opérateur de flux sur les TileItem
*/
inline std::ostream &operator << (std::ostream &out, const TileItem &t);
inline ostream &operator << (ostream &out, const TileItem &t);
template <typename WeightT> struct Edge {
Point points[2];
@ -58,20 +59,31 @@ namespace otb {
/*! Opérateur de flux sur les voisins */
template <typename WeightT>
inline std::ostream &operator << (std::ostream &out, const Edge<WeightT> &edge);
struct CPrintEdge {
const Edge<WeightT> &edge;
const Size &size;
inline CPrintEdge (const Edge<WeightT> &edge, const Size &size);
inline ostream &print (ostream &out) const;
};
template <typename WeightT>
inline std::ostream &printEdge (std::ostream &out, const Edge<WeightT> &edge, const Size &size);
inline CPrintEdge<WeightT> printEdge (const Edge<WeightT> &edge, const Size &size);
/*! Affiche tous les voisins d'un ensemble */
template <typename Edge>
inline std::ostream &printEdges (std::ostream &out, const std::vector<Edge> &edges);
template <typename WeightT>
inline ostream &operator << (ostream& out, const CPrintEdge<WeightT> &cpe) { return cpe.print (out); }
template <typename Edge>
inline std::ostream &printEdges (std::ostream &out, const Edge edges[], const Size &size, const DimEdge edgesCount);
template <typename WeightT>
struct CPrintEdges {
const Edge<WeightT> *edges;
const Size &size;
const DimEdge edgesCount;
inline CPrintEdges (const Edge<WeightT> edges[], const Size &size, const DimEdge edgesCount);
inline ostream &print (ostream &out) const;
};
template <typename WeightT>
inline CPrintEdges<WeightT> printEdges (const Edge<WeightT> edges[], const Size &size, const DimEdge edgesCount);
/*! Affiche tous les voisins d'un ensembles à l'aide de leurs coordonnées */
template <typename Edge>
inline std::ostream &printEdges (std::ostream &out, const std::vector<Edge> &edges, const Size &size);
template <typename WeightT>
inline ostream &operator << (ostream& out, const CPrintEdges<WeightT> &cpe) { return cpe.print (out); }
#include "triskeleArrayTreeBase.tpp"

View File

@ -1,14 +1,14 @@
#ifndef _OTB_TRISKELE_ARRAY_TREE_BASE_TPP
#define _OTB_TRISKELE_ARRAY_TREE_BASE_TPP
inline std::ostream &
operator << (std::ostream &out, const Connectivity &c) {
inline ostream &
operator << (ostream &out, const Connectivity &c) {
BOOST_ASSERT (c >= 0 && c < 4);
return out << connectivityName[c];
}
inline std::ostream &
operator << (std::ostream &out, const TileItem &t) {
inline ostream &
operator << (ostream &out, const TileItem &t) {
BOOST_ASSERT (t >= 0 && t < 3);
return out << tileItemName[t];
}
@ -21,43 +21,50 @@ swapEdge (Edge<WeightT> &a, Edge<WeightT> &b) {
b = c;
}
// ========================================
template <typename WeightT>
inline std::ostream &
operator << (std::ostream &out, const Edge<WeightT> &edge) {
return out << edge.points[0] << ":" << edge.points[1] << ":" << edge.weight;
inline
CPrintEdge<WeightT>::CPrintEdge (const Edge<WeightT> &edge, const Size &size)
: edge (edge),
size (size) {
}
template <typename WeightT>
inline std::ostream &
printEdge (std::ostream &out, const Edge<WeightT> &edge, const Size &size) {
return out << edge.points[0] << ":" << edge.points[1] << ":" << ((uint32_t) edge.weight) << ":"
inline ostream &
CPrintEdge<WeightT>::print (ostream &out) const {
// XXX if WeightT == uint8_t => print char :-(
return out << edge.points[0] << ":" << edge.points[1] << ":" << edge.weight << ":"
<< point2idx (size, edge.points[0]) << ":" << point2idx (size, edge.points[1]);
}
template <typename Edge>
inline std::ostream &
printEdges (std::ostream &out, const std::vector<Edge> &edges) {
for (int i = 0; i < edges.size (); ++i)
out << " " << edges [i];
return out;
template <typename WeightT>
inline CPrintEdge<WeightT>
printEdge (const Edge<WeightT> &edge, const Size &size) {
return CPrintEdge<WeightT> (edge, size);
}
template <typename Edge>
inline std::ostream &
printEdges (std::ostream &out, const Edge edges[], const Size &size, const DimEdge edgesCount) {
// ========================================
template <typename WeightT>
inline
CPrintEdges<WeightT>::CPrintEdges (const Edge<WeightT> edges[], const Size &size, const DimEdge edgesCount)
: edges (edges),
size (size),
edgesCount (edgesCount) {
}
template <typename WeightT>
inline
ostream &
CPrintEdges<WeightT>::print (ostream &out) const {
for (int i = 0; i < edgesCount; ++i)
printEdge (out, edges[i], size) << std::endl;
out << printEdge (edges[i], size) << endl;
return out;
}
template <typename Edge>
inline std::ostream &
printEdges (std::ostream &out, const std::vector<Edge> &edges, const Size &size) {
for (int i = 0; i < edges.size (); ++i)
out << " [" << point2idx (size, edges [i].points[0])
<< " " << point2idx (size, edges [i].points[1])
<< " " << edges [i].weight << "]";
return out;
template <typename WeightT>
inline CPrintEdges<WeightT>
printEdges (const Edge<WeightT> edges[], const Size &size, const DimEdge edgesCount) {
return CPrintEdges<WeightT> (edges, size, edgesCount);
}
#endif // _OTB_TRISKELE_ARRAY_TREE_BASE_TPP

View File

@ -15,7 +15,6 @@ namespace otb {
inline void updateTranscient ();
inline PixelT *getValues ();
inline const PixelT *getValues () const;
inline void printValues () const;
protected:
const Tree &tree;
@ -24,8 +23,12 @@ namespace otb {
inline void free ();
inline void book (const DimImg &leafCount);
ostream &print (ostream &out) const;
friend ostream &operator << (ostream& out, const AttributeProfiles &ap) { return ap.print (out); }
};
#include "AttributeProfiles.tpp"
} // triskele
} // otb

View File

@ -34,14 +34,6 @@ AttributeProfiles<PixelT>::getValues () const {
return values;
}
template<typename PixelT>
inline void
AttributeProfiles<PixelT>::printValues () const {
cout << "AP" << endl;
const Size doubleSize (tree.getSize().width, 2*tree.getSize ().height);
printMap (cout, values, doubleSize, tree.getNodeCount ()) << endl << endl;
}
template<typename PixelT>
inline void
AttributeProfiles<PixelT>::free () {
@ -62,4 +54,13 @@ AttributeProfiles<PixelT>::book (const DimImg &leafCount) {
values = new PixelT[leafCount*2];
}
// ========================================
template<typename PixelT>
ostream &
AttributeProfiles<PixelT>::print (ostream &out) const {
const Size doubleSize (tree.getSize().width, 2*tree.getSize ().height);
out << "AP" << endl
<< printMap (values, doubleSize, tree.getNodeCount ()) << endl << endl;
}
#endif // _OTB_TRISKELE_ATTRIBUTE_PROFILES_TPP

View File

@ -17,6 +17,7 @@ namespace otb {
template<typename PixelT>
inline void cut (vector<vector<PixelT> > &allBands, const AttributeProfiles<PixelT> &attributeProfiles,
const vector<DimImg> &thresholds) const;
virtual inline ostream &print (ostream &out) const { CompAttribute::print (out, "area"); }
protected:
inline void compute ();
};

View File

@ -16,6 +16,7 @@ namespace otb {
template<typename PixelT>
inline AverageAttributes (const Tree &tree, const Raster<PixelT> &raster, const AreaAttributes &areaAttributes);
inline ~AverageAttributes ();
virtual inline ostream &print (ostream &out) const { CompAttribute::print (out, "average"); }
protected:
template<typename PixelT>
inline void compute (const Raster<PixelT> &raster, const AreaAttributes &areaAttributes);

View File

@ -13,6 +13,7 @@ namespace otb {
public:
inline MoIAttributes (const Tree &tree, const AreaAttributes &areaAttributes, const XYAttributes &xyAttributes);
inline ~MoIAttributes ();
virtual inline ostream &print (ostream &out) const { CompAttribute::print (out, "moi"); }
template<typename PixelT>
inline void cut (vector<vector<PixelT> > &allBands, const AttributeProfiles<PixelT> &attributeProfiles,

View File

@ -15,6 +15,7 @@ namespace otb {
public:
inline SDAttributes (const Tree &tree, const AreaAttributes &areaAttributes);
inline ~SDAttributes ();
virtual inline ostream &print (ostream &out) const { CompAttribute::print (out, "sd"); }
template<typename PixelT>
inline void cut (vector<vector<PixelT> > &allBands, const AttributeProfiles<PixelT> &attributeProfiles,

View File

@ -15,6 +15,8 @@ namespace otb {
inline ~WeightAttributes ();
inline void setWeightBounds (Tree &tree);
virtual inline ostream &print (ostream &out) const { CompAttribute<WeightT>::print (out, "weight"); }
};
#include "WeightAttributes.tpp"

View File

@ -9,15 +9,20 @@
namespace otb {
namespace triskele {
using namespace ::triskele;
struct AverageXY {
double x, y;
inline AverageXY () : x(0), y(0) {}
friend ostream &operator << (ostream& out, const AverageXY &xy) { return out << "(" << xy.x << ", " << xy.y << ")"; }
operator DimImg () const { return (DimImg) (x*y); }
};
class XYAttributes : public CompAttributeC<AverageXY> {
public:
inline XYAttributes (const Tree &tree, const AreaAttributes &areaAttributes);
inline ~XYAttributes ();
virtual inline ostream &print (ostream &out) const { CompAttribute::print (out, "xy"); }
protected:
inline void compute (const AreaAttributes &areaAttributes);
};

View File

@ -21,7 +21,8 @@ namespace otb {
inline const AttrT *getValues () const;
inline AttrT *getValues ();
inline AttrT getMaxValue () const;
inline void printValues (const string &msg) const;
virtual inline ostream &print (ostream &out) const { print (out, ""); }
protected:
const Tree &tree;
@ -30,6 +31,9 @@ namespace otb {
inline void free ();
inline void book (const DimImg &leafCount);
ostream &print (ostream &out, const string &msg) const;
friend ostream &operator << (ostream& out, const CompAttribute &ca) { return ca.print (out); }
};
} // triskele

View File

@ -19,6 +19,7 @@ CompAttribute<AttrT>::~CompAttribute () {
template<typename AttrT>
inline void
CompAttribute<AttrT>::updateTranscient () {
// XXX max : leafCount-1
book (tree.getLeafCount ());
}
@ -48,11 +49,11 @@ CompAttribute<AttrT>::getMaxValue () const {
}
template<typename AttrT>
inline void
CompAttribute<AttrT>::printValues (const string &msg) const {
inline ostream &
CompAttribute<AttrT>::print (ostream &out, const string &msg) const {
cout << "values: " << msg << endl;
const Size doubleSize (tree.getSize().width, 2*tree.getSize ().height);
printMap (cout, values, doubleSize, tree.getCompCount ()) << endl << endl;
cout << printMap (values, doubleSize, tree.getCompCount ()) << endl << endl;
}
template<typename AttrT>

View File

@ -96,7 +96,7 @@ namespace otb {
inline const DimNodeId *getChildren () const; // XXX a virer ?
inline const vector<DimImg> &getWeightBounds () const;
inline vector<DimImg> &getWeightBounds ();
inline vector<DimImg> &getWeightBounds ();
// Functions to apply to specific entities
template<typename FuncToApply>
@ -105,15 +105,29 @@ namespace otb {
template<typename FuncToApply>
inline void forEachComp (const FuncToApply &f /* f (DimImg compId) */) const;
template<typename FuncToApply>
inline void forEachNode (const FuncToApply &f /* f (DimNodeId nodeId) */) const;
template<typename FuncToApply>
inline void forEachChild (const DimNodeId &parentId, const FuncToApply &f /* f (DimNodeId childId) */) const;
template<typename FuncToApply>
inline void forEachChildTI (const DimNodeId &parentId, const FuncToApply &f /* f (bool isLeaf, DimImg childId) */) const;
#ifdef ENABLE_LOG
// Print info about the tree
void printTree () const;
#endif
void checkSpare () const;
void check () const;
// XXX void checkWeightCurve (bool incr) const;
// nice ostream
struct CPrintTree {
const Tree &tree;
const bool onRecord;
const DimNodeId nodeCount;
CPrintTree (const Tree &tree, DimNodeId nodeCount);
ostream &print (ostream &out) const;
};
CPrintTree printTree (DimNodeId nodeCount = 0) const;
friend ostream &operator << (ostream& out, const CPrintTree &cpt) { return cpt.print (out); }
};
#include "Tree.tpp"

View File

@ -98,11 +98,18 @@ Tree::forEachLeaf (const FuncToApply &f /* f (DimImg leafId) */) const {
template<typename FuncToApply>
inline void
Tree::forEachComp (const FuncToApply &f /* f (DimImg compId) */) const {
const DimNodeId compCount = getCompCount ();
for (DimNodeId compId = 0; compId < compCount; ++compId)
const DimImg compCount = getCompCount ();
for (DimImg compId = 0; compId < compCount; ++compId)
f (compId);
}
template<typename FuncToApply>
inline void
Tree::forEachNode (const FuncToApply &f /* f (NodeDimImg nodeId) */) const {
for (DimNodeId nodeId = 0; nodeId < nodeCount; ++nodeId)
f (nodeId);
}
template<typename FuncToApply>
inline void
Tree::forEachChild (const DimNodeId &parentId, const FuncToApply &f /* f (DimNodeId childId) */) const {
@ -117,6 +124,10 @@ Tree::forEachChildTI (const DimNodeId &parentId, const FuncToApply &f /* f (bool
for (DimNodeId childId = minChild; childId < maxChild; ++childId) {
const DimNodeId &child (getChildren (childId));
const bool isLeaf = child < leafCount;
if (child >= getNodeCount ()) {
cerr << "coucou Tree::forEachChildTI parentId:" << parentId << " compCount:" << getCompCount () << " minChild:" << minChild << " maxChild:" << maxChild << " childId:" << childId << " child:" << child << endl;
}
BOOST_ASSERT (child < getNodeCount ());
f (isLeaf, isLeaf ? (DimImg) child : (DimImg) (child-leafCount));
}
}

View File

@ -50,10 +50,25 @@ namespace otb {
//void reset ();
inline void addDim (const TreeType &treeType, const DimImg& leafCount, const DimImg& compCount);
inline void addTime (const TimeType &timeType, const double &duration);
ostream &printDim (ostream &out);
ostream &printTime (ostream &out);
// nice ostream
struct CPrintDim {
const TreeStats &treeStats;
CPrintDim (const TreeStats &treeStats);
ostream &print (ostream &out) const;
ostream &print (ostream &out, const TreeStatsDim stats[], const string &msg) const;
};
CPrintDim printDim () const;
friend ostream &operator << (ostream& out, const CPrintDim &cpd) { return cpd.print (out); }
struct CPrintTime {
const TreeStats &treeStats;
CPrintTime (const TreeStats &treeStats);
ostream &print (ostream &out) const;
};
CPrintTime printTime () const;
friend ostream &operator << (ostream& out, const CPrintTime &cpt) { return cpt.print (out); }
private :
ostream &printDim (ostream &out, const TreeStatsDim stats[], const string &msg);
TreeStatsDim leavesStats[TreeTypeCard], compStats[TreeTypeCard];
TreeStatsDouble timeStats[TimeTypeCard];

View File

@ -11,6 +11,8 @@
namespace triskele {
using namespace std;
/*! Image band type */
typedef uint16_t DimChanel; // hyperspectral > 256
@ -32,7 +34,7 @@ namespace triskele {
inline Point (const DimSideImg &abs, const DimSideImg &ord);
};
inline bool operator== (const Point &p1, const Point &p2);
inline std::ostream &operator << (std::ostream &out, const Point &p);
inline ostream &operator << (ostream &out, const Point &p);
extern Point NullPoint;
struct Size {
@ -41,7 +43,7 @@ namespace triskele {
inline Size (const DimSideImg &w, const DimSideImg &h);
};
inline bool operator== (const Size &s1, const Size &s2);
inline std::ostream &operator << (std::ostream &out, const Size &s);
inline ostream &operator << (ostream &out, const Size &s);
extern Size NullSize;
inline DimImg pointToId (const Size &size, const Point &p);
@ -55,7 +57,7 @@ namespace triskele {
inline Rect (const DimSideImg &abs, const DimSideImg &ord, const DimSideImg &w, const DimSideImg &h);
};
inline bool operator== (const Rect &r1, const Rect &r2);
inline std::ostream &operator << (std::ostream &out, const Rect &r);
inline ostream &operator << (ostream &out, const Rect &r);
extern Rect NullRect;
/*! Convertit un point d'un tableau (on peut imaginer une image à 2 dimension) en un index */
@ -64,11 +66,22 @@ namespace triskele {
/*! Convertit un index d'un tableau (on peut imaginer une image à 2 dimension) en point correspondant à des coordonnées */
inline Point idx2point (const Size &size, const DimImg &idx);
static const DimSideImg printMapMaxSide = 20;
static const DimSideImg printMapMaxSide = 25;
/*! Affiche le contenu d'un tableau en spécifiant sa taille */
template <typename DimImg>
inline std::ostream &printMap (std::ostream &out, const DimImg *map, const Size &size, DimNodeId maxValues);
template <typename T>
struct CPrintMap {
const T *map;
const Size &size;
DimNodeId maxValues;
inline CPrintMap (const T *map, const Size &size, DimNodeId maxValues = 0);
inline ostream &print (ostream &out) const;
};
template <typename T>
inline CPrintMap<T> printMap (const T *map, const Size &size, DimNodeId maxValues);
template <typename T>
inline ostream &operator << (ostream& out, const CPrintMap<T> &cpm) { return cpm.print (out); }
#include "triskeleBase.tpp"

View File

@ -19,8 +19,8 @@ operator== (const Point &p1, const Point &p2) {
return p1.x == p2.x && p1.y == p2.y;
}
inline std::ostream &
operator << (std::ostream &out, const Point &p) {
inline ostream &
operator << (ostream &out, const Point &p) {
return out << "(" << p.x << "," << p.y << ")";
}
@ -41,8 +41,8 @@ operator== (const Size &s1, const Size &s2) {
return s1.width == s2.width && s1.height == s2.height;
}
inline std::ostream &
operator << (std::ostream &out, const Size &s) {
inline ostream &
operator << (ostream &out, const Size &s) {
return out << "[" << s.width << "," << s.height << "]";
}
@ -93,8 +93,8 @@ operator== (const Rect &r1, const Rect &r2) {
return r1.x == r2.x && r1.y == r2.y && r1.width == r2.width && r1.height == r2.height;
}
inline std::ostream &
operator << (std::ostream &out, const Rect &r) {
inline ostream &
operator << (ostream &out, const Rect &r) {
return out << "[" << r.x << "," << r.y << " " << r.width << "x" << r.height << "]";
}
@ -107,27 +107,43 @@ idx2point (const Size &size, const DimImg &idx) {
return Point (idx % size.width, idx / size.width);
}
// ========================================
template <typename T>
inline
CPrintMap<T>::CPrintMap (const T *map, const Size &size, DimNodeId maxValues)
: map (map),
size (size),
maxValues (maxValues == 0 ? ((DimNodeId) size.width)*size.height : maxValues) {
}
template <typename T>
inline std::ostream &
printMap (std::ostream &out, const T *map, const Size &size, DimNodeId maxValues) {
inline ostream &
CPrintMap<T>::print (ostream &out) const {
if (size.width > printMapMaxSide || size.height > printMapMaxSide) {
return out << "map too big to print!" << std::endl;
return out << "map too big to print!" << endl;
}
if (maxValues == 0)
maxValues = ((DimNodeId) size.width)*size.height;
const T *map2 = map;
DimNodeId countDown = maxValues;
for (DimSideImg y = 0; y < size.height; ++y) {
for (DimSideImg x = 0; x < size.width; ++x, ++map, --maxValues) {
if (!maxValues)
for (DimSideImg x = 0; x < size.width; ++x, ++map2, --countDown) {
if (!countDown)
return out;
if (*map == DimImg_MAX)
out << " M ";
if ((DimImg (*map2)) == DimImg_MAX)
out << " M ";
else
out << std::setw(3) << ((double) *map) << " ";
// XXX if T == uint8_t => print char :-(
out << setw(3) << *map2 << " ";
}
out << std::endl;
out << endl;
}
return out;
}
template <typename T>
inline CPrintMap<T>
printMap (const T *map, const Size &size, DimNodeId maxValues) {
return CPrintMap<T> (map, size, maxValues);
}
#endif // _OTB_TRISKELE_BASE_TPP

View File

@ -7,6 +7,35 @@
#include <sstream>
#include <boost/date_time/posix_time/posix_time.hpp>
#ifdef ENABLE_SMART_LOG
#ifndef SMART_DEF_LOG
#define SMART_DEF_LOG(name, expr) DEF_LOG (name, expr)
#endif
#ifndef SMART_LOG
#define SMART_LOG(expr) LOG (expr)
#endif
#ifndef SMART_LOG_EXPR
#define SMART_LOG_EXPR(expr) {if (triskele::debug) expr; }
#endif
#else
#ifndef SMART_DEF_LOG
#define SMART_DEF_LOG(name, expr)
#endif
#ifndef SMART_LOG
#define SMART_LOG(expr)
#endif
#ifndef SMART_LOG_EXPR
#define SMART_LOG_EXPR(expr)
#endif
#endif
#ifdef DISABLE_LOG
#ifndef DEF_LOG

View File

@ -1,6 +1,9 @@
#include "Tree.hpp"
#include "ArrayTree/Border.hpp"
#include "ArrayTree/GraphWalker.hpp"
using namespace otb::triskele;
using namespace otb::triskele::arrayTree;
using namespace std;
Tree::Tree (const DimSideImg &width, const DimSideImg &height, unsigned int coreCount)
@ -35,7 +38,7 @@ Tree::clear () {
childCount[0] = childCount[1] = 0;
// XXX dealThreadFill_n avec coreCount
fill_n (leafParents, leafCount*2, DimImg_MAX);
#ifdef SMART_LOG
#ifdef USE_SMART_LOG
fill_n (children, (leafCount-1)*2, 0);
fill_n (childCount, leafCount+1, 0);
#endif
@ -83,14 +86,168 @@ Tree::book (const DimImg &leafCount) {
}
#ifdef ENABLE_LOG
void
Tree::printTree () const {
cout << "tree parent count children" << endl;
Size doubleSize (size.width, 2*size.height);
printMap (cout, leafParents, doubleSize, nodeCount) << endl << endl;
printMap (cout, childCount, size, ((DimNodeId) getCompCount ()) + 1) << endl << endl;
printMap (cout, children, doubleSize, nodeCount) << endl << endl;
Tree::checkSpare () const {
Border border; // default = no border
GraphWalker graphWalker (size, border);
vector<Rect> tiles;
vector<Rect> boundaries;
vector<bool> verticalBoundaries;
graphWalker.setTiles (coreCount, Rect (NullPoint, size), tiles, boundaries, verticalBoundaries);
vector<DimImg> vertexMaxBounds;
vector<DimImg> edgesMaxBounds;
graphWalker.setMaxBounds (tiles, vertexMaxBounds, edgesMaxBounds);
unsigned int tileCount = tiles.size ();
vector<DimImg> maxParents (tileCount);
// check parents
for (unsigned int i = 0; i < tileCount; ++i) {
DimImg base = vertexMaxBounds [i], top = vertexMaxBounds [i+1];
DimImg &maxParent = maxParents [i];
graphWalker.forEachVertexIdx (tiles[i], [this, &base, &top, &maxParent] (DimImg leafId) {
BOOST_ASSERT (leafParents[leafId] >= base);
BOOST_ASSERT (leafParents[leafId] < top);
if (maxParent < leafParents[leafId])
maxParent = leafParents[leafId];
});
}
DimImg *childCountRec = childCount+2;
for (unsigned int i = 0; i < tileCount; ++i) {
DimImg base = vertexMaxBounds [i], maxParent = maxParents [i];
for (DimImg compId = base; compId < maxParent; ++compId) {
BOOST_ASSERT (compParents[compId] > base);
BOOST_ASSERT (compParents[compId] != compId);
BOOST_ASSERT (compParents[compId] < maxParent);
if (compParents[compId] < compId)
BOOST_ASSERT (childCountRec[compParents[compId]] > childCountRec[compId]);
}
BOOST_ASSERT (compParents[maxParent] == DimImg_MAX);
}
{
vector<bool> parentsMap (vertexMaxBounds[tileCount], false);
for (unsigned int i = 0; i < tileCount; ++i) {
graphWalker.forEachVertexIdx (tiles[i], [this, &parentsMap] (DimImg leafId) {
parentsMap [leafParents [leafId]] = true;
});
DimImg base = vertexMaxBounds [i], maxParent = maxParents [i];
for (DimImg compId = base; compId < maxParent; ++compId)
parentsMap [compParents [compId]] = true;
for (DimImg compId = base; compId < maxParent; ++compId)
BOOST_ASSERT (parentsMap [compId]);
}
}
// check weight
// XXX monotone
// check childCount
}
#endif
void
Tree::check () const {
DimImg compCount = getCompCount ();
BOOST_ASSERT (compCount < leafCount);
// check parents
forEachLeaf ([this, &compCount] (const DimImg &leafId) {
// XXX si border => leafParents [leafId] == DimImg_MAX
BOOST_ASSERT (leafParents[leafId] < compCount);
});
forEachComp ([this, &compCount] (const DimImg &compId) {
if (compId == compCount-1)
BOOST_ASSERT (compParents[compId] == DimImg_MAX);
else {
BOOST_ASSERT (compParents[compId] > compId);
BOOST_ASSERT (compParents[compId] < compCount);
}
});
{
vector<bool> parentsMap (compCount, false);
//parentsMap.assign (compCount, false);
forEachNode ([this, &parentsMap] (const DimNodeId &nodeId) {
if (leafParents[nodeId] == DimImg_MAX)
return;
parentsMap [leafParents [nodeId]] = true;
});
for (DimImg compId = 0; compId < compCount; ++compId)
BOOST_ASSERT (parentsMap [compId]);
}
// check weight
// check weightBounds
// check childCount
{
vector<DimImg> childCount2 (compCount, 0);
forEachLeaf ([this, &childCount2] (const DimImg &leafId) {
if (leafParents[leafId] == DimImg_MAX)
// boder
return;
++childCount2 [leafParents [leafId]];
});
forEachComp ([this, &childCount2, &compCount] (const DimImg &compId) {
if (compId == compCount-1)
return;
++childCount2 [compParents [compId]];
});
for (DimImg compId = 0; compId < compCount; ++compId) {
// check count
BOOST_ASSERT (childCount2 [compId] = childCount [compId+1] - childCount[compId]);
// at least 2 children
BOOST_ASSERT (childCount2 [compId] > 1);
}
}
// check children
{
vector<DimNodeId> childrenMap (nodeCount, DimImg_MAX);
forEachComp ([this, &childrenMap] (const DimImg &compId) {
DimNodeId minChild = childCount[compId], maxChild = childCount[compId+1];
for (DimNodeId childId = minChild; childId < maxChild; ++childId) {
DimNodeId child = children[childId];
BOOST_ASSERT (leafParents [child] == compId);
BOOST_ASSERT (childrenMap [child] == DimImg_MAX);
childrenMap [child] = compId;
}
for (DimNodeId childId = minChild+1; childId < maxChild; ++childId) {
BOOST_ASSERT (children[childId-1] < children[childId]);
}
});
for (DimImg child = 0; child < nodeCount-1; ++child)
BOOST_ASSERT (childrenMap [child] != DimImg_MAX);
}
}
// ========================================
Tree::CPrintTree::CPrintTree (const Tree &tree, DimNodeId nodeCount)
: tree (tree),
onRecord (nodeCount),
nodeCount (onRecord ? nodeCount : tree.getNodeCount ()) {
}
ostream &
Tree::CPrintTree::print (ostream &out) const {
Size doubleSize (tree.size.width, 2*tree.size.height);
out << "Tree::printTree: leafCount:" << tree.leafCount
<< " nodeCount:" << (onRecord ? "~" : "") << nodeCount << " compCount:" << nodeCount - tree.leafCount << endl
<< "parent count" << (onRecord ? "" : " children") << endl
<< printMap (tree.leafParents, doubleSize, nodeCount) << endl << endl
<< printMap (tree.childCount + (onRecord ? 2 : 0), tree.size, nodeCount - tree.leafCount + 1) << endl << endl;
if (!onRecord)
out << printMap (tree.children, doubleSize, nodeCount-1) << endl << endl;
if (tree.weightBounds.size ()) {
out << "weightBounds: " << endl
<< printMap (&tree.weightBounds[0], tree.size, tree.weightBounds.size ()) << endl << endl;
} else
return out << "no weightBounds" << endl << endl;
}
Tree::CPrintTree
Tree::printTree (DimNodeId nodeCount) const {
return CPrintTree (*this, nodeCount);
}
// ostream &
// operator << (ostream& out, const Tree::CPrintTree &cpt) {
// return cpt.print (out);
// }

View File

@ -22,6 +22,9 @@ static string timeTypeLabels [TimeTypeCard] = {
"sum All",
};
TreeStats globalTreeStats;
// ========================================
using namespace boost::chrono;
inline string
ns2string (double delta) {
@ -41,11 +44,25 @@ ns2string (double delta) {
return oss.str ();
}
TreeStats globalTreeStats;
// ----------------------------------------
TreeStats::CPrintDim::CPrintDim (const TreeStats &treeStats)
: treeStats (treeStats) {
}
ostream &
TreeStats::CPrintDim::print (ostream &out) const {
bool empty = true;
for (unsigned int i = 0; i < TreeTypeCard; ++i)
if (!(empty = !ba::count (treeStats.leavesStats[i])))
break;
if (empty)
return out;
print (out, treeStats.leavesStats, "Leaf");
return print (out, treeStats.compStats, "Comp");
}
ostream &
TreeStats::printDim (ostream &out, const TreeStatsDim stats[], const string &msg) {
cout << endl
TreeStats::CPrintDim::print (ostream &out, const TreeStatsDim stats[], const string &msg) const {
out << endl
<< setw (11) << left << msg << "\t"
<< setw (3) << left << "Count" << "\t"
<< setw (9) << left << "Mean" << "\t"
@ -54,7 +71,7 @@ TreeStats::printDim (ostream &out, const TreeStatsDim stats[], const string &msg
for (unsigned int i = 0; i < TreeTypeCard; ++i) {
if (!ba::count (stats[i]))
continue;
cout << setw (11) << right << treeTypeLabels [i] << "\t"
out << setw (11) << right << treeTypeLabels [i] << "\t"
<< setw (3) << ba::count (stats[i]) << "\t"
<< setw (9) << DimImg (ba::mean (stats[i])) << "\t"
<< setw (9) << ba::min (stats[i]) << "\t"
@ -64,42 +81,54 @@ TreeStats::printDim (ostream &out, const TreeStatsDim stats[], const string &msg
return out;
}
ostream &
TreeStats::printDim (ostream &out) {
bool empty = true;
for (unsigned int i = 0; i < TreeTypeCard; ++i)
if (!(empty = !ba::count (leavesStats[i])))
break;
if (empty)
return out;
printDim (out, leavesStats, "Leaf");
return printDim (out, compStats, "Comp");
TreeStats::CPrintDim
TreeStats::printDim () const {
return CPrintDim (*this);
}
// ostream&
// operator << (ostream& out, const TreeStats::CPrintDim &cpd) {
// return cpd.print (out);
// }
// ----------------------------------------
TreeStats::CPrintTime::CPrintTime (const TreeStats &treeStats)
: treeStats (treeStats) {
}
ostream &
TreeStats::printTime (ostream &out) {
TreeStats::CPrintTime::print (ostream &out) const {
bool empty = true;
for (unsigned int i = 0; i < TimeTypeCard; ++i)
if (!(empty = !ba::count (timeStats[i])))
if (!(empty = !ba::count (treeStats.timeStats[i])))
break;
if (empty)
return out;
cout << endl
<< setw (11) << left << "Time" << "\t"
<< setw (15) << left << "Sum" << "\t"
<< setw (3) << left << "Count" << "\t"
<< setw (15) << left << "Mean" << "\t"
<< setw (15) << left << "Min" << "\t"
<< setw (15) << left << "Max" << endl;
out << endl
<< setw (11) << left << "Time" << "\t"
<< setw (15) << left << "Sum" << "\t"
<< setw (3) << left << "Count" << "\t"
<< setw (15) << left << "Mean" << "\t"
<< setw (15) << left << "Min" << "\t"
<< setw (15) << left << "Max" << endl;
for (unsigned int i = 0; i < TimeTypeCard; ++i) {
if (!ba::count (timeStats[i]))
if (!ba::count (treeStats.timeStats[i]))
continue;
cout << setw (11) << right << timeTypeLabels[i] << "\t"
<< ns2string (ba::sum (timeStats[i])) << "\t" << setw (3) << ba::count (timeStats[i]) << "\t"
<< ns2string (ba::mean (timeStats[i])) << "\t"
<< ns2string (ba::min (timeStats[i])) << "\t"
<< ns2string (ba::max (timeStats[i]))
<< endl << flush;
out << setw (11) << right << timeTypeLabels[i] << "\t"
<< ns2string (ba::sum (treeStats.timeStats[i])) << "\t" << setw (3) << ba::count (treeStats.timeStats[i]) << "\t"
<< ns2string (ba::mean (treeStats.timeStats[i])) << "\t"
<< ns2string (ba::min (treeStats.timeStats[i])) << "\t"
<< ns2string (ba::max (treeStats.timeStats[i]))
<< endl << flush;
}
return out;
}
TreeStats::CPrintTime
TreeStats::printTime () const {
return CPrintTime (*this);
}
// ostream&
// operator << (ostream& out, const TreeStats::CPrintTime &cpt) {
// return cpt.print (out);
// }
// ========================================

View File

@ -113,9 +113,9 @@ void apGenerator (Option &option) {
}
}
cerr << endl << "*** apGenerator done!" << endl;
globalTreeStats.printDim (cerr);
globalTreeStats.printTime (cerr);
cerr << endl << "*** apGenerator done!" << endl
<< globalTreeStats.printDim () << endl
<< globalTreeStats.printTime ();
}
int