Docker-in-Docker (DinD) capabilities of public runners deactivated. More info

Commit dd44aaae authored by Pierre Aubert's avatar Pierre Aubert
Browse files

Add base of test on generic tree (Quadtree and octree but with N dimentions)

parent c49803f6
Pipeline #96675 passed with stages
in 1 minute and 22 seconds
......@@ -11,7 +11,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
phoenix_create_find_header(PhoenixGraph Graph.h "")
phoenix_create_find(PhoenixGraph phoenix_graph Graph.h "")
add_subdirectory(src)
......
......@@ -8,4 +8,5 @@ add_subdirectory(TEST_DOT_LOOP)
add_subdirectory(TEST_DOT_TOTAL_LOOP)
add_subdirectory(TEST_DOT_REMOVE)
add_subdirectory(TEST_DOT_STR)
add_subdirectory(TEST_PNTREE_LIGHT)
project(Phoenix)
add_executable(test_graph_to_dot main.cpp)
target_link_libraries(test_graph_to_dot phoenix_graph)
add_test(NAME TestGraphToDot
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_graph_to_dot)
......
project(Phoenix)
add_executable(test_graph_to_dot_loop main.cpp)
target_link_libraries(test_graph_to_dot_loop phoenix_graph)
add_test(NAME TestGraphToDotLoop
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_graph_to_dot_loop)
......
project(Phoenix)
add_executable(test_graph_to_dot_remove main.cpp)
target_link_libraries(test_graph_to_dot_remove phoenix_graph)
add_test(NAME TestGraphToDotRemove
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_graph_to_dot_remove)
......
project(Phoenix)
add_executable(test_graph_to_dot_str main.cpp)
target_link_libraries(test_graph_to_dot_str phoenix_graph)
add_test(NAME TestGraphToDotStr
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_graph_to_dot_str)
......
project(Phoenix)
add_executable(test_graph_to_dot_total_loop main.cpp)
target_link_libraries(test_graph_to_dot_total_loop phoenix_graph)
add_test(NAME TestGraphToDotTotalLoop
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_graph_to_dot_total_loop)
......
project(Phoenix)
cmake_minimum_required(VERSION 3.0)
add_executable(test_pntreelight main.cpp)
target_link_libraries(test_pntreelight phoenix_graph)
add_test(NAME TestPNTreeLight
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_pntreelight
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
/***************************************
Auteur : Pierre Aubert
Mail : aubertp7@gmail.com
Licence : CeCILL-C
****************************************/
#include <iostream>
#include "Tree/PNTreeLight.h"
using namespace std;
#define NB_POINT 8lu
#define NB_POINT_TOTAL (NB_POINT*NB_POINT)
#define NB_POINT_3D 8lu
#define NB_POINT_3D_TOTAL (NB_POINT_3D*NB_POINT_3D*NB_POINT_3D)
///Tests the basis of the quadtree
void testBaseQuadTree(){
size_t nbPoint(NB_POINT);
float dXY(5.0f);
float shift(dXY/2.0f);
float posXY(0.0f), sizeXY(((size_t)(2.0f*shift + ((float)(nbPoint - 1lu))*dXY)));
float posTab[] = {posXY, posXY};
float sizeTab[] = {sizeXY, sizeXY};
PNTreeLight<float, size_t, 2> quadTree(posTab, sizeTab, 1.0f);
size_t tabId[NB_POINT_TOTAL], id;
for(size_t i(0lu); i < NB_POINT_TOTAL; ++i){tabId[i] = i;}
float x, y;
float tabPos[2*NB_POINT_TOTAL];
std::ofstream fs;
fs.open("pointAddedInQuadTree.txt");
if(!fs.is_open()) return;
for(size_t i(0lu); i < nbPoint; ++i){
y = shift + ((float)i)*dXY;
for(size_t j(0lu); j < nbPoint; ++j){
x = shift + ((float)j)*dXY;
tabPos[(i*nbPoint + j)*2lu] = x;
tabPos[(i*nbPoint + j)*2lu + 1lu] = y;
id = i*nbPoint + j;
cerr << "Add point " << x << "," << y << "\t, id = " << id << endl;
fs << x << "\t" << y << "\t0" << endl;
if(!quadTree.addElement(&(tabPos[(i*nbPoint + j)*2lu]), tabId+id)){
cerr << "quadTree.addElement : can't add element : Stop" << endl;
i = nbPoint;
break;
}
}
}
fs.close();
std::string fileTxt("quadTree.txt");
if(quadTree.saveGnuplotData(fileTxt)){
std::cout << "testBaseQuadTree : file '" << fileTxt << "' saved" << std::endl;
}else{
std::cerr << "testBaseQuadTree : can't save file '" << fileTxt << "'" << std::endl;
}
float posLastData[] = {11.0f, 19.0f};
const size_t * data = quadTree.getLastData(posLastData);
if(data != NULL) cout << "testBaseQuadTree : data (11.0, 19.0) = " << *data << endl;
else cout << "testBaseQuadTree : data (11.0, 19.0) = NULL" << endl;
}
///Tests the basis of the quadtree
void testBaseQuadTree3d(){
size_t nbPoint(NB_POINT_3D);
float dXY(5.0f);
float shift(dXY/2.0f);
float posXY(0.0f), sizeXY(((size_t)(2.0f*shift + ((float)(nbPoint - 1lu))*dXY)));
float posTab[] = {posXY, posXY, posXY};
float sizeTab[] = {sizeXY, sizeXY, sizeXY};
PNTreeLight<float, size_t, 3> quadTree(posTab, sizeTab);
size_t tabId[NB_POINT_3D_TOTAL], id;
for(size_t i(0lu); i < NB_POINT_3D_TOTAL; ++i){tabId[i] = i;}
float tabPos[3*NB_POINT_3D_TOTAL];
float x,y,z;
std::ofstream fs;
fs.open("pointAddedInQuadTree3d.txt");
if(!fs.is_open()) return;
for(size_t k(0lu); k < nbPoint; ++k){
z = shift + ((float)k)*dXY;
for(size_t i(0lu); i < nbPoint; ++i){
y = shift + ((float)i)*dXY;
for(size_t j(0lu); j < nbPoint; ++j){
x = shift + ((float)j)*dXY;
id = k*nbPoint*nbPoint + i*nbPoint + j;
// cerr << "Add point " << tabPos[0] << "," << tabPos[1] << "," << tabPos[2] << "\t, id = " << id << endl;
tabPos[(k*nbPoint*nbPoint + i*nbPoint + j)*3lu] = x;
tabPos[(k*nbPoint*nbPoint + i*nbPoint + j)*3lu + 1lu] = y;
tabPos[(k*nbPoint*nbPoint + i*nbPoint + j)*3lu + 2lu] = z;
fs << x << "\t" << y << "\t"<< z << endl;
if(!quadTree.addElement(&(tabPos[(k*nbPoint*nbPoint + i*nbPoint + j)*3lu]), tabId+id)){
cerr << "quadTree.addElement : can't add element : Stop" << endl;
i = nbPoint;
break;
}
}
}
}
fs.close();
std::string fileTxt("quadTree3d.txt");
if(quadTree.saveGnuplotData(fileTxt)){
std::cout << "testBaseQuadTree3d : file '" << fileTxt << "' saved" << std::endl;
}else{
std::cerr << "testBaseQuadTree3d : can't save file '" << fileTxt << "'" << std::endl;
}
float posLastData[] = {11.0f, 19.0f, 10.0f};
const size_t * data = quadTree.getLastData(posLastData);
if(data != NULL) cout << "testBaseQuadTree3d : data (11.0, 19.0) = " << *data << endl;
else cout << "testBaseQuadTree3d : data (11.0, 19.0) = NULL" << endl;
}
int main(int argc, char** argv){
testBaseQuadTree();
testBaseQuadTree3d();
return 0;
}
project(Phoenix)
cmake_minimum_required(VERSION 2.8)
file(GLOB_RECURSE graph_sources "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
add_library(phoenix_graph SHARED ${graph_sources})
install(TARGETS phoenix_graph LIBRARY DESTINATION ${LIBRARY_DIRECTORY} ARCHIVE DESTINATION ${LIBRARY_DIRECTORY})
file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
install(FILES ${headers} DESTINATION include/PhoenixGraph)
project(Phoenix)
cmake_minimum_required(VERSION 2.8)
file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
install(FILES ${headers} DESTINATION include/PhoenixGraph/Tree)
/***************************************
Auteur : Pierre Aubert
Mail : aubertp7@gmail.com
Licence : CeCILL-C
****************************************/
#ifndef __PNTREELIGHT_H__
#define __PNTREELIGHT_H__
#include "PNTreeLightNode.h"
///@brief Describes only the PNTreeClass tree, without the size
template<typename T, typename U, unsigned char N>
class PNTreeLight{
public:
PNTreeLight();
PNTreeLight(T pos[N], T size[N], T sizeLimit = 1e-5);
virtual ~PNTreeLight();
PNTreeLight & operator = (const PNTreeLight<T,U,N> & other);
bool saveGnuplotData(const std::string & fileName);
bool saveGnuplotData(std::ofstream & fs, T height);
void setPosition(T pos[N]);
void setSize(T size[N]);
void setLimitSize(T limitSize);
bool addElement(T * posData, U * data);
const U * getLastData(T * posData) const;
const U * getCloserData(T * posData) const;
const U * getCloserDataDist(T & distFromCloserData, T * posData) const;
protected:
void copyPNTreeLight(const PNTreeLight<T,U,N> & other);
private:
PNTreeLight(const PNTreeLight<T,U,N> & other);
void initialisationPNTreeLight(T pos[N], T size[N], T sizeLimit);
///Position of the hyper cube
T p_pos[N];
///Size of the hyper cube
T p_size[N];
///Size limit of the cells
T p_sizeLimit;
///Table of the children of the current node
PNTreeLightNode<T,U,N> p_node;
};
#include "PNTreeLight_impl.h"
#endif
/***************************************
Auteur : Pierre Aubert
Mail : aubertp7@gmail.com
Licence : CeCILL-C
****************************************/
#include "PNTreeLightNode.h"
///Says is the neighbours search is finised
/** @param tabIsNeighbourChecked : tab of the neighbours search status (true if checked, false if not)
* @param nbNeighbour : number of neighbours in the table
* @return true if all the tabIsNeighbourChecked is true, false otherwise
*/
bool isNeighbourSearchFinised(const bool * tabIsNeighbourChecked, unsigned int nbNeighbour){
bool b(true);
for(unsigned int i(0u); i < nbNeighbour; ++i){
b &= tabIsNeighbourChecked[i];
}
return b;
}
/***************************************
Auteur : Pierre Aubert
Mail : aubertp7@gmail.com
Licence : CeCILL-C
****************************************/
#ifndef __PNTREE_LIGHT_NODE_H__
#define __PNTREE_LIGHT_NODE_H__
#include <iostream>
#include <fstream>
template<typename T, typename U, unsigned char N>
class PNTreeLightNode;
///@brief Describe a Quad tree
/** T : Type of the positions
* U : type of the data pointors to be stored
* N : number of dimensions of the N Tree
*/
template<typename T, typename U, unsigned char N>
class PNTreeLightNode{
public:
PNTreeLightNode();
virtual ~PNTreeLightNode();
bool addElement(T * posData, U * data, const T pos[N], const T size[N], const T sizeLimit);
void clear();
bool saveGnuplotData(const std::string & fileName, T pos[N], T size[N]);
bool saveGnuplotData(std::ofstream & fs, T height, T pos[N], T size[N]);
const U * getData() const;
U * getData();
const T * getDataPos() const;
T * getDataPos();
const U * getLastData(const T * posData, const T pos[N], const T size[N]) const;
bool getCloserData(U*& closerData, T & distFromCloserData, bool * tabIsNeighbourChecked, unsigned int nbNeighbour,
const T * posData, const T pos[N], const T size[N]) const;
const PNTreeLightNode<T, U, N> * getChildFromPos(T childPos[N], const T * posData, const T pos[N], const T size[N]) const;
PNTreeLightNode<T, U, N> * getChildFromPos(T childPos[N], const T * posData, const T pos[N], const T size[N]);
void getIndexOfChildFromPos(unsigned char index[N], const T posData[N], const T pos[N], const T size[N]) const;
void getIndexOfChildFromPos(unsigned char index[N], T posData[N], T pos[N], T size[N]);
unsigned char getFullIndexChild(unsigned char index[N]) const;
const PNTreeLightNode<T, U, N> * getTabChildren() const;
PNTreeLightNode<T, U, N> * getTabChildren();
const PNTreeLightNode<T, U, N> * getChild(unsigned char childId) const;
PNTreeLightNode<T, U, N> * getChild(unsigned char childId);
protected:
void copyPNTreeLightNode(const PNTreeLightNode<T, U, N> & other);
private:
PNTreeLightNode(const PNTreeLightNode<T, U, N> & other);
bool split(const T pos[N], const T size[N], T sizeLimit);
void initialisationPNTreeLightNode();
///Position of the data in the cell
T * p_posData;
///Data of the node
U * p_data;
///Position of the data in the hyper cube
PNTreeLightNode<T,U,N> * p_tableChildren;
};
bool isNeighbourSearchFinised(const bool * tabIsNeighbourChecked, unsigned int nbNeighbour);
#include "PNTreeLightNode_impl.h"
#endif
/***************************************
Auteur : Pierre Aubert
Mail : aubertp7@gmail.com
Licence : CeCILL-C
****************************************/
#ifndef __PNTREE_LIGHT_NODE_H_IMPL__
#define __PNTREE_LIGHT_NODE_H_IMPL__
#include <string.h>
#include <math.h>
#include "pstatic_computation.h"
#include "PNTreeLightNode.h"
///Default constructor of PNTreeLightNode
template<typename T, typename U, unsigned char N>
PNTreeLightNode<T, U, N>::PNTreeLightNode(){
initialisationPNTreeLightNode();
}
///Copy constructor of PNTreeLightNode
/** @param other : class to copy
*/
template<typename T, typename U, unsigned char N>
PNTreeLightNode<T, U, N>::PNTreeLightNode(const PNTreeLightNode<T, U, N> & other){
copyPNTreeLightNode(other);
}
///Destructeur of PNTreeLightNode
template<typename T, typename U, unsigned char N>
PNTreeLightNode<T, U, N>::~PNTreeLightNode(){
clear();
}
///Get the size of the child
/** @param[out] childSize : child size
* @param parentSize : parent size
*/
template<typename T, unsigned char N>
void makeHalfSize(T childSize[N], const T parentSize[N]){
for(unsigned char i(0lu); i < N; ++i){
childSize[i] = parentSize[i]/2.f;
}
}
///Check the size of the childs of a N Tree
/** @param halfSizeChild : table of half size of the current N Tree
* @param sizeLimit : limit of the cell size
* @return true if everything is OK, false if the childs are too small
*/
template<typename T, unsigned char N>
bool checkSizeLimitLight(const T halfSizeChild[N], T sizeLimit){
for(unsigned char i(0); i < N; ++i){
if(halfSizeChild[i] < sizeLimit) return false;
}
return true;
}
///Add an element in the PNTreeLightNode
/** @param posData : position of the data
* @param data : pointer to the data we want to sort
* @param pos : position of the current node
* @param size : size of the current node
* @param sizeLimit : limit of the cell size
* @return true on success, false otherwise
*/
template<typename T, typename U, unsigned char N>
bool PNTreeLightNode<T, U, N>::addElement(T * posData, U * data, const T pos[N], const T size[N], T sizeLimit){
if(!checkSizeLimitLight<T, N>(size, sizeLimit)){
return false;
}
if(p_tableChildren == NULL){
if(p_data == NULL){ //The cell is empty
p_data = data;
p_posData = posData;
return true;
}else{ //There is a data in the cell
if(!split(pos, size, sizeLimit)) return false;
return addElement(posData, data, pos, size, sizeLimit);
}
}else{ //There are children
T childPos[N];
PNTreeLightNode<T, U, N> * child = getChildFromPos(childPos, posData, pos, size);
if(child == NULL){
return false;
}else{
T childSize[N];
makeHalfSize<T,N>(childSize, size);
return child->addElement(posData, data, childPos, childSize, sizeLimit);
}
}
}
///Saves the PNTreeLightNode into a txt file for gnuplot
/** @param fileName : name of the text file we want to write
* @param pos : position of the current node
* @param size : size of the current node
* @return true on success, false otherwise
*/
template<typename T, typename U, unsigned char N>
bool PNTreeLightNode<T, U, N>::saveGnuplotData(const std::string & fileName, T pos[N], T size[N]){
if(fileName == "") return false;
std::ofstream fs;
fs.open(fileName);
if(!fs.is_open()){return false;}
bool b = saveGnuplotData(fs, 0, pos, size);
fs.close();
return b;
}
///Saves the PNTreeLightNode into a txt file for gnuplot
/** @param fs : text file we want to write
* @param height : height of the quad to draw
* @param pos : position of the current node
* @param size : size of the current node
* @return true on success, false otherwise
*/
template<typename T, typename U, unsigned char N>
bool PNTreeLightNode<T, U, N>::saveGnuplotData(std::ofstream & fs, T height, T pos[N], T size[N]){
if(N == 2){
fs << pos[0] << "\t" << pos[1] << "\t" << height << std::endl;
fs << (pos[0] + size[0]) << "\t" << pos[1] << "\t" << height << std::endl;
fs << (pos[0] + size[0]) << "\t" << (pos[1] + size[1]) << "\t" << height << std::endl;
fs << pos[0] << "\t" << (pos[1] + size[1]) << "\t" << height << std::endl;
fs << pos[0] << "\t" << pos[1] << "\t" << height << std::endl;
}else if(N == 3){
T px0(pos[0]), px1(pos[0] + size[0]);
T py0(pos[1]), py1(pos[1] + size[1]);
T pz0(pos[2]), pz1(pos[2] + size[2]);
//lower quad
fs << px0 << "\t" << py0 << "\t" << pz0 << std::endl;
fs << px1 << "\t" << py0 << "\t" << pz0 << std::endl;
fs << px1 << "\t" << py1 << "\t" << pz0 << std::endl;
fs << px0 << "\t" << py1 << "\t" << pz0 << std::endl;
fs << px0 << "\t" << py0 << "\t" << pz0 << std::endl;
fs << std::endl;
//upper quad
fs << px0 << "\t" << py0 << "\t" << pz1 << std::endl;
fs << px1 << "\t" << py0 << "\t" << pz1 << std::endl;
fs << px1 << "\t" << py1 << "\t" << pz1 << std::endl;
fs << px0 << "\t" << py1 << "\t" << pz1 << std::endl;
fs << px0 << "\t" << py0 << "\t" << pz1 << std::endl;
fs << std::endl;
//Lines on Oz axis
fs << px0 << "\t" << py0 << "\t" << pz0 << std::endl;
fs << px0 << "\t" << py0 << "\t" << pz1 << std::endl;
fs << std::endl;
fs << px0 << "\t" << py1 << "\t" << pz0 << std::endl;
fs << px0 << "\t" << py1 << "\t" << pz1 << std::endl;
fs << std::endl;
fs << px1 << "\t" << py1 << "\t" << pz0 << std::endl;
fs << px1 << "\t" << py1 << "\t" << pz1 << std::endl;
fs << std::endl;
fs << px1 << "\t" << py0 << "\t" << pz0 << std::endl;
fs << px1 << "\t" << py0 << "\t" << pz1 << std::endl;
}
fs << std::endl;
if(p_tableChildren != NULL){
T childSize[N], posChild[N];
makeHalfSize<T,N>(childSize, size);
for(unsigned char i(0); i < PPower<2, N>::Value; ++i){
for(unsigned char k(0); k < N; ++k){
posChild[k] = pos[k] + ((i >> k) & 1)*childSize[k];
}
p_tableChildren[i].saveGnuplotData(fs, height + 1, posChild, childSize);
}
}
return true;
}
///Clear the PNTreeLightNode content
template<typename T, typename U, unsigned char N>
void PNTreeLightNode<T, U, N>::clear(){
if(p_tableChildren != NULL){
for(unsigned char i(0); i < PPower<2, N>::Value; ++i){
PNTreeLightNode<T, U, N> * child = &(p_tableChildren[i]);
child->clear();
}
delete [] p_tableChildren;
p_tableChildren = NULL;
}
p_data = NULL;
}
///Get the data of the last node in the N tree
/** @param posData : position of the data
* @param pos : position of the current node
* @param size : size of the current node
* @return data of the last node in the N tree
*/
template<typename T, typename U, unsigned char N>
const U * PNTreeLightNode<T, U, N>::getLastData(const T * posData, const T pos[N], const T size[N]) const{
if(p_tableChildren == NULL){
if(p_data == NULL) return NULL;
else return p_data;
}else{
T childPos[N];
const PNTreeLightNode<T, U, N> * child = getChildFromPos(childPos, posData, pos, size);
if(child == NULL) return NULL;
else{
T childSize[N];
makeHalfSize<T,N>(childSize, size);
return child->getLastData(posData, pos, childSize);
}
}
}