GRALE
gridtree.h
1 /*
2 
3  This file is a part of GRALE, a library to facilitate the simulation
4  and inversion of gravitational lenses.
5 
6  Copyright (C) 2008-2012 Jori Liesenborgs
7 
8  Contact: jori.liesenborgs@gmail.com
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 
24 */
25 
26 #ifndef GRALE_GRIDTREE_H
27 
28 #define GRALE_GRIDTREE_H
29 
30 #include "graleconfig.h"
31 #include "realtype.h"
32 #include <vector>
33 
34 // TODO: for debugging
35 #include <stdio.h>
36 
37 namespace grale
38 {
39 
40 class GRALE_IMPORTEXPORT GridNodeBase
41 {
42 public:
43  enum GridNodeType { TreeNode, WeightNode };
44 protected:
45  GridNodeBase(GridNodeType t, GridNodeBase *pParent, int childNumber, int level)
46  {
47  m_nodeType = t;
48  m_pParent = pParent;
49  m_childNumber = childNumber;
50  m_level = level;
51  }
52 public:
53  virtual ~GridNodeBase() { }
54  virtual GridNodeBase *createCopy() const = 0;
55  GridNodeType getNodeType() const { return m_nodeType; }
56  GridNodeBase *getParent() const { return m_pParent; }
57  int getChildNumber() const { return m_childNumber; }
58  int getLevel() const { return m_level; }
59  void setChildInfo(GridNodeBase *pParent, int childNumber) { m_pParent = pParent; m_childNumber = childNumber; }
60  virtual void setLevel(int level) { m_level = level; }
61 
62  // TODO: for debugging
63  virtual void print(int tab = 0) = 0;
64 private:
65  GridNodeType m_nodeType;
66  GridNodeBase *m_pParent;
67  int m_childNumber;
68  int m_level;
69 };
70 
71 class GRALE_IMPORTEXPORT GridWeightNode : public GridNodeBase
72 {
73 public:
74  GridWeightNode(float w, GridNodeBase *pParent, int childNumber, int level) : GridNodeBase(WeightNode, pParent, childNumber, level)
75  { m_weight = w; }
76  ~GridWeightNode() { }
77  float getWeight() const { return m_weight; }
78  void setWeight(float w) { m_weight = w; }
79  GridNodeBase *createCopy() const { return new GridWeightNode(m_weight, 0, -1, 0); } // don't copy parent info to avoid double deletions
80 
81  // TODO: for debugging
82  void print(int tab = 0) { for (int i = 0 ; i < tab ; i++) printf(" "); printf("%g (%d)\n",(double)m_weight, getLevel()); }
83 private:
84  float m_weight;
85 };
86 
87 class GRALE_IMPORTEXPORT GridTreeNode : public GridNodeBase
88 {
89 public:
90  GridTreeNode(GridNodeBase *pParent, int childNumber, int level, int numChildren = 4) : GridNodeBase(TreeNode, pParent, childNumber, level)
91  {
92  m_pChild.resize(numChildren);
93  for (int i = 0 ; i < numChildren ; i++)
94  m_pChild[i] = 0;
95  }
96 
97  ~GridTreeNode()
98  {
99  for (int i = 0 ; i < m_pChild.size() ; i++)
100  if (m_pChild[i])
101  delete m_pChild[i];
102  }
103 
104  int getNumberOfChildren() const { return m_pChild.size(); }
105 
106  bool isValid() const
107  {
108  for (int i = 0 ; i < m_pChild.size() ; i++)
109  {
110  if (m_pChild[i] == 0)
111  return false;
112  if (m_pChild[i]->getNodeType() == TreeNode)
113  {
114  const GridTreeNode *pNode = (const GridTreeNode *)m_pChild[i];
115 
116  if (!pNode->isValid())
117  return false;
118  }
119  }
120  return true;
121  }
122 
123  void setNode(int i, GridNodeBase *pNode)
124  {
125  if (m_pChild[i])
126  delete m_pChild[i];
127  m_pChild[i] = pNode;
128 
129  if (pNode)
130  {
131  m_pChild[i]->setChildInfo(this, i);
132  m_pChild[i]->setLevel(getLevel()+1);
133  }
134  }
135 
136  void setNodeNoLevel(int i, GridNodeBase *pNode)
137  {
138  if (m_pChild[i])
139  delete m_pChild[i];
140  m_pChild[i] = pNode;
141 
142  if (pNode)
143  {
144  m_pChild[i]->setChildInfo(this, i);
145  }
146  }
147 
148  GridNodeBase *createCopy() const
149  {
150  GridTreeNode *pNewNode = new GridTreeNode(0, -1, 0, m_pChild.size());
151  for (int i = 0 ; i < m_pChild.size() ; i++)
152  {
153  GridNodeBase *pNode = m_pChild[i];
154  if (pNode)
155  pNode = pNode->createCopy();
156  pNewNode->setNode(i, pNode);
157  }
158  return pNewNode;
159  }
160 
161  const GridNodeBase *getChild(int i) const { return m_pChild[i]; }
162  GridNodeBase *getChild(int i) { return m_pChild[i]; }
163 
164  void setLevel(int level)
165  {
166  GridNodeBase::setLevel(level);
167  for (int i = 0 ; i < m_pChild.size() ; i++)
168  if (m_pChild[i])
169  m_pChild[i]->setLevel(level+1);
170  }
171 
172  GridNodeBase *extractChild(int i)
173  {
174  GridNodeBase *pChild = m_pChild[i];
175  m_pChild[i] = 0;
176  return pChild;
177  }
178 
179  // TODO: for debugging
180  void print(int tab = 0) { for (int i = 0 ; i < tab ; i++) printf(" "); printf("Node (%d)\n", getLevel()); for (int i = 0 ; i < m_pChild.size() ; i++) { if (!m_pChild[i]) { for (int i = 0 ; i < tab+1 ; i++) printf(" "); printf("NULL\n"); } else { m_pChild[i]->print(tab+1); } } }
181 private:
182  std::vector<GridNodeBase *> m_pChild;
183 };
184 
185 } // end namespace
186 
187 #endif // GRALE_GRIDTREE_H
188