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 33 - (show annotations) (download) (as text)
Wed Sep 7 04:38:51 2016 UTC (7 years, 6 months ago) by rtomiyasu
File MIME type: text/x-c++src
File size: 11033 byte(s)
The output format for base-centered monoclinic cells was corrected.
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 <cmath>
29 #include "FracMat.hh"
30 #include "TreeLattice.hh"
31
32 // RelationMatrix TreeLattice::m_rel_mat;
33
34 TreeLattice::TreeLattice()
35 {
36 m_root = NULL;
37 m_root_on_left = NULL;
38 m_root_on_right = NULL;
39 HeadIsTail = false;
40 m_is_set_sort_criteria = false;
41 m_count_Q = 0;
42 m_detS = 0.0;
43 }
44
45
46 TreeLattice::TreeLattice(const TreeLattice& rhs)
47 {
48 m_root = NULL;
49 m_root_on_left = NULL;
50 m_root_on_right = NULL;
51
52 if( rhs.m_root != NULL ) m_root = new NodeB(*rhs.m_root);
53 HeadIsTail = rhs.HeadIsTail;
54 if( rhs.m_root_on_left != NULL )
55 {
56 m_root_on_left = new NodeB(*rhs.m_root_on_left);
57 }
58 if( rhs.m_root_on_right != NULL )
59 {
60 m_root_on_right = new NodeB(*rhs.m_root_on_right);
61 }
62 m_is_set_sort_criteria = rhs.m_is_set_sort_criteria;
63 m_count_Q = rhs.m_count_Q;
64 m_detS = rhs.m_detS;
65 }
66
67
68 TreeLattice::~TreeLattice()
69 {
70 delete m_root;
71 m_root = NULL;
72
73 delete m_root_on_left;
74 m_root_on_left = NULL;
75
76 delete m_root_on_right;
77 m_root_on_right = NULL;
78 }
79
80 TreeLattice& TreeLattice::operator=(const TreeLattice& rhs)
81 {
82 if (this != &rhs)
83 {
84 clear();
85
86 if( rhs.m_root != NULL ) m_root = new NodeB(*rhs.m_root);
87 HeadIsTail = rhs.HeadIsTail;
88 if( rhs.m_root_on_left != NULL )
89 {
90 m_root_on_left = new NodeB(*rhs.m_root_on_left);
91 }
92 if( rhs.m_root_on_right != NULL )
93 {
94 m_root_on_right = new NodeB(*rhs.m_root_on_right);
95 }
96 m_is_set_sort_criteria = rhs.m_is_set_sort_criteria;
97 m_count_Q = rhs.m_count_Q;
98 m_detS = rhs.m_detS;
99 }
100 return *this;
101 }
102
103
104 void TreeLattice::clear()
105 {
106 delete m_root;
107 m_root = NULL;
108
109 delete m_root_on_left;
110 m_root_on_left = NULL;
111
112 delete m_root_on_right;
113 m_root_on_right = NULL;
114
115 HeadIsTail = false;
116 m_is_set_sort_criteria = false;
117 m_count_Q = 0;
118 m_detS = 0.0;
119 }
120
121 void TreeLattice::setCountOfQ()
122 {
123 if( m_root == NULL )
124 {
125 m_count_Q = 0;
126 }
127 else
128 {
129 set<Int4> index_tray;
130 m_root->count(index_tray);
131 if( m_root_on_left != NULL )
132 {
133 m_root_on_left->count(index_tray);
134 }
135 if( m_root_on_right != NULL )
136 {
137 m_root_on_right->count(index_tray);
138 }
139
140 m_count_Q = index_tray.size();
141 }
142 }
143
144
145 void TreeLattice::setAreaSquare()
146 {
147 set<Bud> budtray;
148 putRootBuds(budtray);
149
150 assert( !( budtray.empty() ) );
151
152 m_detS = budtray.begin()->cross_product_312();
153 }
154
155
156 void TreeLattice::putRootBuds(set<Bud>& budtray) const
157 {
158 budtray.clear();
159 if( m_root == NULL ) return;
160
161 if( HeadIsTail )
162 {
163 m_root->putRootBud(m_root->Upper(), budtray);
164 }
165 else if( m_root_on_left != NULL )
166 {
167 m_root->putRootBud(m_root_on_left->Right(), budtray);
168 m_root_on_left->putRootBud(m_root->Left(), budtray);
169 if( m_root_on_right != NULL ) m_root_on_right->putRootBud(m_root->Right(), budtray);
170 }
171 else if( m_root_on_right != NULL )
172 {
173 m_root->putRootBud(m_root_on_right->Left(), budtray);
174 m_root_on_right->putRootBud(m_root->Right(), budtray);
175 }
176 else
177 {
178 m_root->putRootBud(-1, budtray);
179 }
180 }
181
182
183 void TreeLattice::putBud(set<Bud>& budtray) const
184 {
185 budtray.clear();
186 if( m_root == NULL ) return;
187
188 if( HeadIsTail )
189 {
190 m_root->putBud(m_root->Upper(), budtray);
191 }
192 else if( m_root_on_left != NULL )
193 {
194 m_root->putBud(m_root_on_left->Right(), budtray);
195 m_root_on_left->putBud(m_root->Left(), budtray);
196 if( m_root_on_right != NULL ) m_root_on_right->putBud(m_root->Right(), budtray);
197 }
198 else if( m_root_on_right != NULL )
199 {
200 m_root->putBud(m_root_on_right->Left(), budtray);
201 m_root_on_right->putBud(m_root->Right(), budtray);
202 }
203 else
204 {
205 m_root->putBud(-1, budtray);
206 }
207 }
208
209
210 //bool TreeLattice::putQuadraticForm(SymMat<Double>& Q, multimap<Int4, VecDat3<Int4> >& qindex_hkl) const
211 //{
212 // static const VecDat3<Int4> hkl100(1,0,0);
213 // static const VecDat3<Int4> hkl010(0,1,0);
214 // static const VecDat3<Int4> hkl_1_10(-1,-1,0);
215 //
216 // qindex_hkl.clear();
217 // if( m_root == NULL ) return false;
218 //
219 // if(m_root->Left() >= 0)
220 // {
221 // qindex_hkl.insert( multimap<Int4, VecDat3<Int4> >::value_type( m_root->Left(), hkl100 ) );
222 // }
223 // if(m_root->Right() >= 0)
224 // {
225 // qindex_hkl.insert( multimap<Int4, VecDat3<Int4> >::value_type( m_root->Right(), hkl010 ) );
226 // }
227 //
228 // if( m_root_on_left != NULL )
229 // {
230 // if(m_root_on_left->Right() >= 0)
231 // {
232 // qindex_hkl.insert( multimap<Int4, VecDat3<Int4> >::value_type( m_root_on_left->Right(), hkl_1_10 ) );
233 // }
234 //
235 // m_root->putQuadraticForm(hkl100, hkl010, qindex_hkl);
236 // m_root_on_left->putQuadraticForm(hkl010, hkl_1_10, qindex_hkl);
237 // if( m_root_on_right != NULL ) m_root_on_right->putQuadraticForm(hkl_1_10, hkl100, qindex_hkl);
238 // }
239 // else if( m_root_on_right != NULL )
240 // {
241 // if(m_root_on_right->Left() >= 0)
242 // {
243 // qindex_hkl.insert( multimap<Int4, VecDat3<Int4> >::value_type( m_root_on_right->Left(), hkl_1_10 ) );
244 // }
245 //
246 // m_root->putQuadraticForm(hkl100, hkl010, qindex_hkl);
247 // m_root_on_right->putQuadraticForm(hkl_1_10, hkl100, qindex_hkl);
248 // }
249 // else
250 // {
251 // m_root->putQuadraticForm(hkl100, hkl010, qindex_hkl);
252 // }
253 //
254 // if( qindex_hkl.size() < 3 ) return false;
255 //
256 // const vector<QData>& qdata = VCData::putPeakQData();
257 // NRMat<Int4> icoef(3,3);
258 // NRVec<Double> qvalue(3);
259 //
260 // multimap<Int4, VecDat3<Int4> >::const_iterator it = qindex_hkl.begin();
261 // icoef[0][0] = it->second[0]*it->second[0];
262 // icoef[0][1] = it->second[1]*it->second[1];
263 // icoef[0][2] = it->second[0]*it->second[1]*2;
264 // qvalue[0] = qdata[(it++)->first].q;
265 // icoef[1][0] = it->second[0]*it->second[0];
266 // icoef[1][1] = it->second[1]*it->second[1];
267 // icoef[1][2] = it->second[0]*it->second[1]*2;
268 // qvalue[1] = qdata[(it++)->first].q;
269 // icoef[2][0] = it->second[0]*it->second[0];
270 // icoef[2][1] = it->second[1]*it->second[1];
271 // icoef[2][2] = it->second[0]*it->second[1]*2;
272 // qvalue[2] = qdata[(it++)->first].q;
273 //
274 // const FracMat inv_mat = FInverse3( icoef );
275 // assert( Q.size() == 2 );
276 //
277 // 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;
278 // 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;
279 // 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;
280 //
281 // return true;
282 //}
283
284
285 void TreeLattice::putQuadraticForm(SymMat<VCData>& Q) const
286 {
287 assert(Q.size() == 2);
288 if( m_root == NULL ) return;
289 if( m_root->IsBud() ) return;
290
291 set<Bud> budtray;
292 this->putRootBuds(budtray);
293 Q(0,0) = budtray.begin()->Q1();
294 Q(1,1) = budtray.begin()->Q2();
295 Q(0,1) = ( Q(0,0) + Q(1,1) - budtray.begin()->Q3() )/2;
296 }
297
298
299 void TreeLattice::print(ostream& os, const Double& minQ, const Double& maxQ) const
300 {
301 if( m_root == NULL ) return;
302 if( m_root->IsBud() ) return;
303
304 os << "* Number of used peak positions: " << this->putCountOfQ() << endl;
305 SymMat<VCData> Q(2);
306 this->putQuadraticForm(Q);
307
308 const Double det_Inv_Q = 1.0/( Q(0,0).Value()*Q(1,1).Value() - Q(0,1).Value()*Q(0,1).Value() );
309 SymMat<Double> Inv_Q(2);
310 Inv_Q(0,0) = Q(1,1).Value()*det_Inv_Q;
311 Inv_Q(1,1) = Q(0,0).Value()*det_Inv_Q;
312 Inv_Q(0,1) = -Q(0,1).Value()*det_Inv_Q;
313
314 Double a = sqrt(Q(0,0).Value());
315 Double b = sqrt(Q(1,1).Value());
316 os << "* (a*, b*, \\gamma*): (" << a << ", " << b << ", " << acos(Q(0,1).Value()/(a*b))*180.0/M_PI << ")\n";
317
318 a = sqrt(Inv_Q(0,0));
319 b = sqrt(Inv_Q(1,1));
320 os << "* (a, b, \\gamma): (" << a << ", " << b << ", " << acos(Inv_Q(0,1)/(a*b))*180.0/M_PI << ")\n";
321
322 if( HeadIsTail )
323 {
324 os.width(15);
325 if( m_root->Upper() < 0 ) os << -1;
326 else os << m_root->Upper() + 1; // HeadIsTail is true.
327
328 os.width(5);
329 os << " > ";
330 if( m_root->Upper() < 0 ) m_root->print(os, 20, -1, maxQ);
331 else m_root->print(os, 20, m_root->Upper(), maxQ); // HeadIsTail is true.
332 os << endl;
333 }
334 else if( m_root_on_left != NULL || m_root_on_right != NULL )
335 {
336 os.width(15);
337 if( m_root_on_left != NULL )
338 {
339 if( m_root_on_left->Right() < 0 ) os << -1;
340 else os << m_root_on_left->Right() + 1;
341
342 os.width(5);
343 os << " > ";
344 m_root->print(os, 20, m_root_on_left->Right(), maxQ);
345 }
346 else
347 {
348 if( m_root_on_right->Left() < 0 ) os << -1;
349 else os << m_root_on_right->Left() + 1;
350
351 os.width(5);
352 os << " > ";
353 m_root->print(os, 20, m_root_on_right->Left(), maxQ);
354 }
355 os << endl;
356
357 if( m_root_on_left != NULL )
358 {
359 os.width(15);
360 if( m_root->Left() < 0 ) os << -1;
361 else os << m_root->Left() + 1;
362 os.width(5);
363 os << " > ";
364
365 m_root_on_left->print(os, 20, m_root->Left(), maxQ);
366 os << endl;
367 }
368
369 if( m_root_on_right != NULL )
370 {
371 os.width(15);
372 if( m_root->Right() < 0 ) os << -1;
373 else os << m_root->Right() + 1;
374 os.width(5);
375 os << " > ";
376
377 m_root_on_right->print(os, 20, m_root->Right(), maxQ);
378 os << endl;
379 }
380 }
381 else
382 {
383 os << endl;
384 os.width(15);
385 if( m_root->Left() >= 0 && m_root->Right() >= 0 && m_root->Upper() >= 0 )
386 {
387 Double ans = ( VCData::putPeakPos(m_root->Left()).q + VCData::putPeakPos(m_root->Right()).q ) * 2.0
388 - VCData::putPeakPos(m_root->Upper()).q;
389 if(ans < minQ) os << "<MinQ";
390 else os << ans;
391 }
392 else os << -1;
393
394 os.width(5);
395 os << " > ";
396 if( m_root->Upper() < 0 ) m_root->print(os, 20, -1, maxQ);
397 else m_root->print(os, 20, m_root->Upper(), maxQ); // HeadIsTail is true.
398 os << endl;
399 }
400 }

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