Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Conograph/trunk/src/utility_data_structure/TreeLattice.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations) (download) (as text)
Fri Feb 22 04:51:31 2013 UTC (11 years, 1 month ago) by rtomiyasu
File MIME type: text/x-c++src
File size: 10373 byte(s)


1 /*
2 * The MIT License
3
4 Conograph (powder auto-indexing program)
5
6 Copyright (c) <2012> <Ryoko Oishi-Tomiyasu, KEK>
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 *
26 */
27 #include <algorithm>
28 #include "FracMat.hh"
29 #include "TreeLattice.hh"
30
31 // RelationMatrix TreeLattice::m_rel_mat;
32
33 TreeLattice::TreeLattice()
34 {
35 m_root = NULL;
36 m_root_on_left = NULL;
37 m_root_on_right = NULL;
38 HeadIsTail = false;
39 m_is_set_sort_criteria = false;
40 m_count_Q = 0;
41 m_detS = 0.0;
42 }
43
44
45 TreeLattice::TreeLattice(const TreeLattice& rhs)
46 {
47 m_root = NULL;
48 m_root_on_left = NULL;
49 m_root_on_right = NULL;
50
51 if( rhs.m_root != NULL ) m_root = new NodeB(*rhs.m_root);
52 HeadIsTail = rhs.HeadIsTail;
53 if( rhs.m_root_on_left != NULL )
54 {
55 m_root_on_left = new NodeB(*rhs.m_root_on_left);
56 }
57 if( rhs.m_root_on_right != NULL )
58 {
59 m_root_on_right = new NodeB(*rhs.m_root_on_right);
60 }
61 m_is_set_sort_criteria = rhs.m_is_set_sort_criteria;
62 m_count_Q = rhs.m_count_Q;
63 m_detS = rhs.m_detS;
64 }
65
66
67 TreeLattice::~TreeLattice()
68 {
69 delete m_root;
70 m_root = NULL;
71
72 delete m_root_on_left;
73 m_root_on_left = NULL;
74
75 delete m_root_on_right;
76 m_root_on_right = NULL;
77 }
78
79 TreeLattice& TreeLattice::operator=(const TreeLattice& rhs)
80 {
81 if (this != &rhs)
82 {
83 clear();
84
85 if( rhs.m_root != NULL ) m_root = new NodeB(*rhs.m_root);
86 HeadIsTail = rhs.HeadIsTail;
87 if( rhs.m_root_on_left != NULL )
88 {
89 m_root_on_left = new NodeB(*rhs.m_root_on_left);
90 }
91 if( rhs.m_root_on_right != NULL )
92 {
93 m_root_on_right = new NodeB(*rhs.m_root_on_right);
94 }
95 m_is_set_sort_criteria = rhs.m_is_set_sort_criteria;
96 m_count_Q = rhs.m_count_Q;
97 m_detS = rhs.m_detS;
98 }
99 return *this;
100 }
101
102
103 void TreeLattice::clear()
104 {
105 delete m_root;
106 m_root = NULL;
107
108 delete m_root_on_left;
109 m_root_on_left = NULL;
110
111 delete m_root_on_right;
112 m_root_on_right = NULL;
113
114 HeadIsTail = false;
115 m_is_set_sort_criteria = false;
116 m_count_Q = 0;
117 m_detS = 0.0;
118 }
119
120 void TreeLattice::setCountOfQ()
121 {
122 if( m_root == NULL )
123 {
124 m_count_Q = 0;
125 }
126 else
127 {
128 set<Int4> index_tray;
129 m_root->count(index_tray);
130 if( m_root_on_left != NULL )
131 {
132 m_root_on_left->count(index_tray);
133 }
134 if( m_root_on_right != NULL )
135 {
136 m_root_on_right->count(index_tray);
137 }
138
139 m_count_Q = index_tray.size();
140 }
141 }
142
143
144 void TreeLattice::setAreaSquare()
145 {
146 set<Bud> budtray;
147 putRootBuds(budtray);
148
149 assert( !( budtray.empty() ) );
150
151 m_detS = budtray.begin()->cross_product_312();
152 }
153
154
155 void TreeLattice::putRootBuds(set<Bud>& budtray) const
156 {
157 budtray.clear();
158 if( m_root == NULL ) return;
159
160 if( HeadIsTail )
161 {
162 m_root->putRootBud(m_root->Upper(), budtray);
163 }
164 else if( m_root_on_left != NULL )
165 {
166 m_root->putRootBud(m_root_on_left->Right(), budtray);
167 m_root_on_left->putRootBud(m_root->Left(), budtray);
168 if( m_root_on_right != NULL ) m_root_on_right->putRootBud(m_root->Right(), budtray);
169 }
170 else if( m_root_on_right != NULL )
171 {
172 m_root->putRootBud(m_root_on_right->Left(), budtray);
173 m_root_on_right->putRootBud(m_root->Right(), budtray);
174 }
175 else
176 {
177 m_root->putRootBud(-1, budtray);
178 }
179 }
180
181
182 void TreeLattice::putBud(set<Bud>& budtray) const
183 {
184 budtray.clear();
185 if( m_root == NULL ) return;
186
187 if( HeadIsTail )
188 {
189 m_root->putBud(m_root->Upper(), budtray);
190 }
191 else if( m_root_on_left != NULL )
192 {
193 m_root->putBud(m_root_on_left->Right(), budtray);
194 m_root_on_left->putBud(m_root->Left(), budtray);
195 if( m_root_on_right != NULL ) m_root_on_right->putBud(m_root->Right(), budtray);
196 }
197 else if( m_root_on_right != NULL )
198 {
199 m_root->putBud(m_root_on_right->Left(), budtray);
200 m_root_on_right->putBud(m_root->Right(), budtray);
201 }
202 else
203 {
204 m_root->putBud(-1, budtray);
205 }
206 }
207
208
209 bool TreeLattice::putQuadraticForm(SymMat<Double>& Q, multimap<Int4, VecDat3<Int4> >& qindex_hkl) const
210 {
211 static const VecDat3<Int4> hkl100(1,0,0);
212 static const VecDat3<Int4> hkl010(0,1,0);
213 static const VecDat3<Int4> hkl_1_10(-1,-1,0);
214
215 qindex_hkl.clear();
216 if( m_root == NULL ) return false;
217
218 if(m_root->Left() >= 0)
219 {
220 qindex_hkl.insert( multimap<Int4, VecDat3<Int4> >::value_type( m_root->Left(), hkl100 ) );
221 }
222 if(m_root->Right() >= 0)
223 {
224 qindex_hkl.insert( multimap<Int4, VecDat3<Int4> >::value_type( m_root->Right(), hkl010 ) );
225 }
226
227 if( m_root_on_left != NULL )
228 {
229 if(m_root_on_left->Right() >= 0)
230 {
231 qindex_hkl.insert( multimap<Int4, VecDat3<Int4> >::value_type( m_root_on_left->Right(), hkl_1_10 ) );
232 }
233
234 m_root->putQuadraticForm(hkl100, hkl010, qindex_hkl);
235 m_root_on_left->putQuadraticForm(hkl010, hkl_1_10, qindex_hkl);
236 if( m_root_on_right != NULL ) m_root_on_right->putQuadraticForm(hkl_1_10, hkl100, qindex_hkl);
237 }
238 else if( m_root_on_right != NULL )
239 {
240 if(m_root_on_right->Left() >= 0)
241 {
242 qindex_hkl.insert( multimap<Int4, VecDat3<Int4> >::value_type( m_root_on_right->Left(), hkl_1_10 ) );
243 }
244
245 m_root->putQuadraticForm(hkl100, hkl010, qindex_hkl);
246 m_root_on_right->putQuadraticForm(hkl_1_10, hkl100, qindex_hkl);
247 }
248 else
249 {
250 m_root->putQuadraticForm(hkl100, hkl010, qindex_hkl);
251 }
252
253 if( qindex_hkl.size() < 3 ) return false;
254
255 const vector<QData>& qdata = VCData::putPeakQData();
256 NRMat<Int4> icoef(3,3);
257 NRVec<Double> qvalue(3);
258
259 multimap<Int4, VecDat3<Int4> >::const_iterator it = qindex_hkl.begin();
260 icoef[0][0] = it->second[0]*it->second[0];
261 icoef[0][1] = it->second[1]*it->second[1];
262 icoef[0][2] = it->second[0]*it->second[1]*2;
263 qvalue[0] = qdata[(it++)->first].q;
264 icoef[1][0] = it->second[0]*it->second[0];
265 icoef[1][1] = it->second[1]*it->second[1];
266 icoef[1][2] = it->second[0]*it->second[1]*2;
267 qvalue[1] = qdata[(it++)->first].q;
268 icoef[2][0] = it->second[0]*it->second[0];
269 icoef[2][1] = it->second[1]*it->second[1];
270 icoef[2][2] = it->second[0]*it->second[1]*2;
271 qvalue[2] = qdata[(it++)->first].q;
272
273 const FracMat inv_mat = FInverse3( icoef );
274 assert( Q.size() == 2 );
275
276 Q(0,0) = ( inv_mat.mat[0][0]*qvalue[0] + inv_mat.mat[0][1]*qvalue[1] + inv_mat.mat[0][2]*qvalue[2] ) / inv_mat.denom;
277 Q(1,1) = ( inv_mat.mat[1][0]*qvalue[0] + inv_mat.mat[1][1]*qvalue[1] + inv_mat.mat[1][2]*qvalue[2] ) / inv_mat.denom;
278 Q(0,1) = ( inv_mat.mat[2][0]*qvalue[0] + inv_mat.mat[2][1]*qvalue[1] + inv_mat.mat[2][2]*qvalue[2] ) / inv_mat.denom;
279
280 return true;
281 }
282
283
284 void TreeLattice::print(ostream& os, const Double& minQ, const Double& maxQ) const
285 {
286 if( m_root == NULL ) return;
287 if( m_root->IsBud() ) return;
288
289 os << "* count : " << this->putCountOfQ() << endl;
290
291 if( HeadIsTail )
292 {
293 os << "* This topograph contains a super-basis : ";
294 set<Bud> budtray;
295 this->putRootBuds(budtray);
296 os << "(" << budtray.begin()->Q3() << ",";
297 os << budtray.begin()->Q1() << ",";
298 os << budtray.begin()->Q2() << ")";
299 os << endl;
300
301 os.width(15);
302 if( m_root->Upper() < 0 ) os << -1;
303 else os << m_root->Upper() + 1; // HeadIsTail is true.
304
305 os.width(5);
306 os << " > ";
307 if( m_root->Upper() < 0 ) m_root->print(os, 20, -1, maxQ);
308 else m_root->print(os, 20, m_root->Upper(), maxQ); // HeadIsTail is true.
309 os << endl;
310 }
311 else if( m_root_on_left != NULL || m_root_on_right != NULL )
312 {
313 os << "* This topograph contains a super-basis : ";
314 set<Bud> budtray;
315 this->putRootBuds(budtray);
316 os << "(" << budtray.begin()->Q3() << ",";
317 os << budtray.begin()->Q1() << ",";
318 os << budtray.begin()->Q2() << ")";
319 os << endl;
320
321 os.width(15);
322 if( m_root_on_left != NULL )
323 {
324 if( m_root_on_left->Right() < 0 ) os << -1;
325 else os << m_root_on_left->Right() + 1;
326
327 os.width(5);
328 os << " > ";
329 m_root->print(os, 20, m_root_on_left->Right(), maxQ);
330 }
331 else
332 {
333 if( m_root_on_right->Left() < 0 ) os << -1;
334 else os << m_root_on_right->Left() + 1;
335
336 os.width(5);
337 os << " > ";
338 m_root->print(os, 20, m_root_on_right->Left(), maxQ);
339 }
340 os << endl;
341
342 if( m_root_on_left != NULL )
343 {
344 os.width(15);
345 if( m_root->Left() < 0 ) os << -1;
346 else os << m_root->Left() + 1;
347 os.width(5);
348 os << " > ";
349
350 m_root_on_left->print(os, 20, m_root->Left(), maxQ);
351 os << endl;
352 }
353
354 if( m_root_on_right != NULL )
355 {
356 os.width(15);
357 if( m_root->Right() < 0 ) os << -1;
358 else os << m_root->Right() + 1;
359 os.width(5);
360 os << " > ";
361
362 m_root_on_right->print(os, 20, m_root->Right(), maxQ);
363 os << endl;
364 }
365 }
366 else
367 {
368 os << endl;
369 os.width(15);
370 if( m_root->Left() >= 0 && m_root->Right() >= 0 && m_root->Upper() >= 0 )
371 {
372 Double ans = ( VCData::putPeakPos(m_root->Left()).q + VCData::putPeakPos(m_root->Right()).q ) * 2.0
373 - VCData::putPeakPos(m_root->Upper()).q;
374 if(ans < minQ) os << "<MinQ";
375 else os << ans;
376 }
377 else os << -1;
378
379 os.width(5);
380 os << " > ";
381 if( m_root->Upper() < 0 ) m_root->print(os, 20, -1, maxQ);
382 else m_root->print(os, 20, m_root->Upper(), maxQ); // HeadIsTail is true.
383 os << endl;
384 }
385 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26