1 /* Copyright (C) 2010 Atsushi Togo */
2 /* All rights reserved. */
3 
4 /* This file is part of spglib. */
5 
6 /* Redistribution and use in source and binary forms, with or without */
7 /* modification, are permitted provided that the following conditions */
8 /* are met: */
9 
10 /* * Redistributions of source code must retain the above copyright */
11 /*   notice, this list of conditions and the following disclaimer. */
12 
13 /* * Redistributions in binary form must reproduce the above copyright */
14 /*   notice, this list of conditions and the following disclaimer in */
15 /*   the documentation and/or other materials provided with the */
16 /*   distribution. */
17 
18 /* * Neither the name of the phonopy project nor the names of its */
19 /*   contributors may be used to endorse or promote products derived */
20 /*   from this software without specific prior written permission. */
21 
22 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26 /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28 /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30 /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31 /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32 /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33 /* POSSIBILITY OF SUCH DAMAGE. */
34 
35 #include <stdio.h>
36 #include "hall_symbol.h"
37 #include "spg_database.h"
38 #include "spacegroup.h"
39 #include "symmetry.h"
40 #include "mathfunc.h"
41 
42 static int M_bcc[3][3] = {
43   { 0, 1, 1 },
44   { 1, 0, 1 },
45   { 1, 1, 0 },
46 };
47 static int M_fcc[3][3] = {
48   {-1, 1, 1 },
49   { 1,-1, 1 },
50   { 1, 1,-1 },
51 };
52 static int M_ac[3][3] = {
53   { 1, 0, 0 },
54   { 0, 1, 1 },
55   { 0,-1, 1 },
56 };
57 static int M_bc[3][3] = {
58   { 1, 0, 1 },
59   { 0, 1, 0 },
60   {-1, 0, 1 },
61 };
62 static int M_cc[3][3] = {
63   { 1,-1, 0 },
64   { 1, 1, 0 },
65   { 0, 0, 1 },
66 };
67 static int M_rc[3][3] = {
68   { 1, 0, 1 },
69   {-1, 1, 1 },
70   { 0,-1, 1 },
71 };
72 
73 static double M_bcc_inv[3][3] = {
74   {-0.5, 0.5, 0.5},
75   { 0.5,-0.5, 0.5},
76   { 0.5, 0.5,-0.5},
77 };
78 static double M_fcc_inv[3][3] = {
79   { 0.0, 0.5, 0.5},
80   { 0.5, 0.0, 0.5},
81   { 0.5, 0.5, 0.0},
82 };
83 static double M_ac_inv[3][3] = {
84   { 1.0, 0.0, 0.0},
85   { 0.0, 0.5,-0.5},
86   { 0.0, 0.5, 0.5},
87 };
88 static double M_bc_inv[3][3] = {
89   { 0.5, 0.0,-0.5},
90   { 0.0, 1.0, 0.0},
91   { 0.5, 0.0, 0.5},
92 };
93 static double M_cc_inv[3][3] = {
94   { 0.5, 0.5, 0.0},
95   {-0.5, 0.5, 0.0},
96   { 0.0, 0.0, 1.0},
97 };
98 static double M_rc_inv[3][3] = {
99   { 2./3,-1./3,-1./3},
100   { 1./3, 1./3,-2./3},
101   { 1./3, 1./3, 1./3},
102 };
103 
104 /* See: R. W. Grosse-Kunstleve, Acta Cryst. (1999). A55, 383-395 */
105 /* */
106 /* S is the Smith normal form, S = U*M*V */
107 /* M = R - I, where R is virtical stack of generator rotation matrices */
108 /* and I is virtical stack of identity matrices. */
109 /* */
110 /* Origin shift is given by (V*S+*U)*dw where dw is translations */
111 /* corresponding to those obtained by symmetry finder and from */
112 /* International table. */
113 /* S+ is given by the operations of inversion of the diagonal elements */
114 /* and then transpose. */
115 
116 static double tricli_VSpU[][3][9] =
117 {
118   { /* 1 */
119     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
120     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
121     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
122   },
123   { /* 2 */
124     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
125     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
126     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
127   },
128 };
129 
130 static int tricli_generators[][3][9] =
131 {
132   { /* 1 */
133     {  1, 0, 0, 0, 1, 0, 0, 0, 1, },
134     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
135     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
136   },
137   { /* 2 */
138     {  1, 0, 0, 0, 1, 0, 0, 0, 1, },
139     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
140     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
141   },
142 };
143 
144 static double monocli_VSpU[][3][9] =
145 {
146   { /* 1 */
147     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
148     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
149     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
150   },
151   { /* 2 */
152     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
153     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
154     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
155   },
156   { /* 3 */
157     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
158     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
159     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
160   },
161   { /* 4 */
162     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
163     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
164     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
165   },
166   { /* 5 */
167     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
168     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
169     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
170   },
171   { /* 6 */
172     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
173     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
174     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
175   },
176   { /* 7 */
177     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
178     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
179     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
180   },
181   { /* 8 */
182     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
183     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
184     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
185   },
186   { /* 9 */
187     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
188     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
189     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
190   },
191 };
192 
193 static double monocli_A_VSpU[][3][9] =
194 {
195   { /* 1 */
196     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
197     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
198     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
199   },
200   { /* 2 */
201     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
202     { 0, -1, 0,  0,  0,  0,  0,  0,  0, },
203     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
204   },
205   { /* 3 */
206     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
207     { 0, -1, 0,  0,  0,  0,  0,  0,  0, },
208     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
209   },
210   { /* 4 */
211     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
212     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
213     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
214   },
215   { /* 5 */
216     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
217     { 0, -1, 0,  0,  0,  0,  0,  0,  0, },
218     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
219   },
220   { /* 6 */
221     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
222     { 0, -1, 0,  0,  0,  0,  0,  0,  0, },
223     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
224   },
225   { /* 7 */
226     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
227     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
228     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
229   },
230   { /* 8 */
231     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
232     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
233     { 0, -1, 0, 0, 1.0/2, 0,  0,  0,  0, },
234   },
235   { /* 9 */
236     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
237     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
238     { 0, 1, 0, 0, -1.0/2, 0,  0,  0,  0, },
239   },
240 };
241 
242 static double monocli_B_VSpU[][3][9] =
243 {
244   { /* 1 */
245     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
246     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
247     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
248   },
249   { /* 2 */
250     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
251     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
252     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
253   },
254   { /* 3 */
255     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
256     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
257     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
258   },
259   { /* 4 */
260     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
261     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
262     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
263   },
264   { /* 5 */
265     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
266     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
267     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
268   },
269   { /* 6 */
270     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
271     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
272     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
273   },
274   { /* 7 */
275     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
276     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
277     { -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, },
278   },
279   { /* 8 */
280     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
281     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
282     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
283   },
284   { /* 9 */
285     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
286     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
287     { 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
288   },
289 };
290 
291 static double monocli_C_VSpU[][3][9] =
292 {
293   { /* 1 */
294     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
295     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
296     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
297   },
298   { /* 2 */
299     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
300     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
301     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
302   },
303   { /* 3 */
304     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
305     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
306     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
307   },
308   { /* 4 */
309     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
310     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
311     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
312   },
313   { /* 5 */
314     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
315     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
316     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
317   },
318   { /* 6 */
319     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
320     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
321     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
322   },
323   { /* 7 */
324     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
325     { 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
326     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
327   },
328   { /* 8 */
329     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
330     { -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, },
331     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
332   },
333   { /* 9 */
334     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
335     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
336     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
337   },
338 };
339 
340 static double monocli_I_VSpU[][3][9] =
341 {
342   { /* 1 */
343     { -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, },
344     { 1.0/2, -1, 0,  0,  0,  0,  0,  0,  0, },
345     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
346   },
347   { /* 2 */
348     { -1, 1.0/2, 0,  0,  0,  0,  0,  0,  0, },
349     { 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
350     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
351   },
352   { /* 3 */
353     { -1, 0, 1.0/2,  0,  0,  0,  0,  0,  0, },
354     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
355     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
356   },
357   { /* 4 */
358     { 0, 1, 0,  0,  0,  0,  0,  0,  0, },
359     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
360     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
361   },
362   { /* 5 */
363     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
364     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
365     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
366   },
367   { /* 6 */
368     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
369     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
370     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
371   },
372   { /* 7 */
373     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
374     { 0, -1, 0, 1.0/2, 0, -1.0/2,  0,  0,  0, },
375     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
376   },
377   { /* 8 */
378     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
379     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
380     { 1, -1.0/2, 0, -1.0/2, 0, 0,  0,  0,  0, },
381   },
382   { /* 9 */
383     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
384     { 1, 0, -1.0/2, -1.0/2, 0, 0,  0,  0,  0, },
385     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
386   },
387 };
388 
389 static int monocli_generators[][3][9] =
390 {
391   { /* 1 */
392     {  1, 0, 0, 0, -1, 0, 0, 0, -1, },
393     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
394     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
395   },
396   { /* 2 */
397     {  -1, 0, 0, 0, 1, 0, 0, 0, -1, },
398     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
399     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
400   },
401   { /* 3 */
402     {  -1, 0, 0, 0, -1, 0, 0, 0, 1, },
403     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
404     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
405   },
406   { /* 4 */
407     {  -1, 0, 0, 0, 1, 0, 0, 0, 1, },
408     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
409     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
410   },
411   { /* 5 */
412     {  1, 0, 0, 0, -1, 0, 0, 0, 1, },
413     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
414     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
415   },
416   { /* 6 */
417     {  1, 0, 0, 0, 1, 0, 0, 0, -1, },
418     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
419     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
420   },
421   { /* 7 */
422     {  1, 0, 0, 0, -1, 0, 0, 0, -1, },
423     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
424     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
425   },
426   { /* 8 */
427     {  -1, 0, 0, 0, 1, 0, 0, 0, -1, },
428     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
429     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
430   },
431   { /* 9 */
432     {  -1, 0, 0, 0, -1, 0, 0, 0, 1, },
433     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
434     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
435   },
436 };
437 
438 static double ortho_VSpU[][3][9] =
439 {
440   { /* 1 */
441     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
442     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
443     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
444   },
445   { /* 2 */
446     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
447     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
448     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
449   },
450   { /* 3 */
451     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
452     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
453     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
454   },
455   { /* 4 */
456     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
457     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
458     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
459   },
460   { /* 5 */
461     { -1.0/2, 0, 0, 0, 0, 0, 0, 0, 0, },
462     { 0, 0, 0, 0, -1.0/2, 0, 0, 0, 0, },
463     { 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, },
464   },
465 };
466 
467 static double ortho_F_VSpU[][3][9] =
468 {
469   { /* 1 */
470     { 0, 1.0/2, 0, -1.0/4, -1.0/4, 0,  0,  0,  0, },
471     { 0, -1.0/2, 0, -1.0/4, -1.0/4, 0,  0,  0,  0, },
472     { 0, -1.0/2, 0, -1.0/4, 3.0/4, 0,  0,  0,  0, },
473   },
474   { /* 2 */
475     { 0, 1, 0, 0, -1, 0,  0,  0,  0, },
476     { 0, 0, 0, 0, -1, 0,  0,  0,  0, },
477     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
478   },
479   { /* 3 */
480     { 0, -1, 0, 0, 1, 0,  0,  0,  0, },
481     { 0, 0, 0, 0, -1, 0,  0,  0,  0, },
482     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
483   },
484   { /* 4 */
485     { 0, -1, 0, 0, 1, 0,  0,  0,  0, },
486     { 0, 0, 0, 0, -1, 0,  0,  0,  0, },
487     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
488   },
489   { /* 5 */
490     { 0, 1, 0, 0, 0, 0, 0, -1.0/2, 0, },
491     { 0, 0, 0, 0, 0, 0, 0, -1.0/2, 0, },
492     { 0, 0, 0, 0, 1, 0, 0, -1.0/2, 0, },
493   },
494 };
495 
496 static double ortho_I_VSpU[][3][9] =
497 {
498   { /* 1 */
499     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
500     { 1.0/2, -1.0/2, 0, -1.0/2, 0, 0,  0,  0,  0, },
501     { -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
502   },
503   { /* 2 */
504     { -1.0/2, 0, 0, 0, 1.0/2, 0,  0,  0,  0, },
505     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
506     { -1.0/2, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
507   },
508   { /* 3 */
509     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
510     { 0, -1, 0, 1.0/2, 0, 0,  0,  0,  0, },
511     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
512   },
513   { /* 4 */
514     { -1.0/2, 0, 0, 0, 1.0/2, 0,  0,  0,  0, },
515     { -1.0/2, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
516     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
517   },
518   { /* 5 */
519     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
520     { 0, 0, -1.0/2, 0, -1, 0, 1.0/2, 0, 0, },
521     { 0, 0, -1.0/2, 0, 0, 0, 0, 0, 0, },
522   },
523 };
524 static double ortho_A_VSpU[][3][9] =
525 {
526   { /* 1 */
527     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
528     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
529     { 0, 1, 0, 0, -1.0/2, 0,  0,  0,  0, },
530   },
531   { /* 2 */
532     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
533     { 0, -1, 0, 0, 0, 0,  0,  0,  0, },
534     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
535   },
536   { /* 3 */
537     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
538     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
539     { 0, -1, 0, 0, 1.0/2, 0,  0,  0,  0, },
540   },
541   { /* 4 */
542     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
543     { 0, -1, 0, 0, 0, 0,  0,  0,  0, },
544     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
545   },
546   { /* 5 */
547     { -1.0/2, 0, 0, 0, 0, 0, 0, 0, 0, },
548     { 0, -1, 0, 0, 0, -1.0/2, 0, 0, 0, },
549     { 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, },
550   },
551 };
552 
553 static double ortho_B_VSpU[][3][9] =
554 {
555   { /* 1 */
556     { -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
557     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
558     { 1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
559   },
560   { /* 2 */
561     { 0, 0, 0, -1, 0, 0,  0,  0,  0, },
562     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
563     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
564   },
565   { /* 3 */
566     { 0, 0, 0, -1, 0, 0,  0,  0,  0, },
567     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
568     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
569   },
570   { /* 4 */
571     { -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
572     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
573     { -1.0/2, 0, 0, 1.0/2, 0, 0,  0,  0,  0, },
574   },
575   { /* 5 */
576     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
577     { 0, 0, 0, 0, -1.0/2, 0, 0, 0, 0, },
578     { 0, 0, 0, -1, 0, 0, 1.0/2, 0, 0, },
579   },
580 };
581 
582 static double ortho_C_VSpU[][3][9] =
583 {
584   { /* 1 */
585     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
586     { -1.0/2, 0, 0, 1, 0, 0,  0,  0,  0, },
587     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
588   },
589   { /* 2 */
590     { -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, },
591     { 1.0/2, 0, 0, -1, 0, 0,  0,  0,  0, },
592     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
593   },
594   { /* 3 */
595     { 0, 0, 0, -1, 0, 0,  0,  0,  0, },
596     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
597     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
598   },
599   { /* 4 */
600     { 0, 0, 0, -1, 0, 0,  0,  0,  0, },
601     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
602     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
603   },
604   { /* 5 */
605     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
606     { 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, },
607     { 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, },
608   },
609 };
610 
611 static int ortho_generators[][3][9] =
612 {
613   { /* 1 */
614     {  -1, 0, 0, 0, -1, 0, 0, 0, 1, },
615     {  1, 0, 0, 0, -1, 0, 0, 0, -1, },
616     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
617   },
618   { /* 2 */
619     {  -1, 0, 0, 0, -1, 0, 0, 0, 1, },
620     {  -1, 0, 0, 0, 1, 0, 0, 0, 1, },
621     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
622   },
623   { /* 3 */
624     {  1, 0, 0, 0, 1, 0, 0, 0, -1, },
625     {  1, 0, 0, 0, -1, 0, 0, 0, -1, },
626     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
627   },
628   { /* 4 */
629     {  1, 0, 0, 0, 1, 0, 0, 0, -1, },
630     {  -1, 0, 0, 0, 1, 0, 0, 0, 1, },
631     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
632   },
633   { /* 5 */
634     {  -1, 0, 0, 0, -1, 0, 0, 0, 1, },
635     {  1, 0, 0, 0, -1, 0, 0, 0, -1, },
636     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
637   },
638 };
639 
640 static double tetra_VSpU[][3][9] =
641 {
642   { /* 1 */
643     { -1.0/2, 1.0/2, 0,  0,  0,  0,  0,  0,  0, },
644     { -1.0/2, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
645     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
646   },
647   { /* 2 */
648     { -1, 0, 0, 0, 1.0/2, 0,  0,  0,  0, },
649     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
650     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
651   },
652   { /* 3 */
653     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
654     { -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, },
655     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
656   },
657   { /* 4 */
658     { -1.0/2, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
659     { 1.0/2, -1.0/2, 0,  0,  0,  0,  0,  0,  0, },
660     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
661   },
662   { /* 5 */
663     { -1, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
664     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
665     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
666   },
667   { /* 6 */
668     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
669     { 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
670     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
671   },
672   { /* 7 */
673     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
674     { -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, },
675     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
676   },
677   { /* 8 */
678     { -1, 0, 0, 0, 1.0/2, 0, 0, 0, 0, },
679     { 0, 0, 0, 0, -1.0/2, 0, 0, 0, 0, },
680     { 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, },
681   },
682 };
683 
684 static double tetra_I_VSpU[][3][9] =
685 {
686   { /* 1 */
687     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
688     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
689     { 0, -1, 0,  0,  0,  0,  0,  0,  0, },
690   },
691   { /* 2 */
692     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
693     { 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
694     { 1, 0, -1, 0, 0, 0,  0,  0,  0, },
695   },
696   { /* 3 */
697     { -1, 0, 0, 0, 0, 0,  0,  0,  0, },
698     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
699     { -1, 0, 0, 0, -1, 0,  0,  0,  0, },
700   },
701   { /* 4 */
702     { -3.0/4, 1.0/4, 1.0/4,  0,  0,  0,  0,  0,  0, },
703     { -1.0/4, -1.0/4, -1.0/4,  0,  0,  0,  0,  0,  0, },
704     { -1.0/2, 1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, },
705   },
706   { /* 5 */
707     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
708     { -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, },
709     { 1, 0, -1, -1, 0, 0,  0,  0,  0, },
710   },
711   { /* 6 */
712     { -3.0/4, 1.0/4, 0, 0, 1.0/4, 0,  0,  0,  0, },
713     { -1.0/4, -1.0/4, 0, 0, -1.0/4, 0,  0,  0,  0, },
714     { -1.0/2, 1.0/2, 0, 0, -1.0/2, 0,  0,  0,  0, },
715   },
716   { /* 7 */
717     { 0, 2, 0, -1.0/2, 0, -1,  0,  0,  0, },
718     { 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
719     { 0, -1, 0, 0, 0, 0,  0,  0,  0, },
720   },
721   { /* 8 */
722     { -1, 0, 0, 0, -1, 0, 1.0/2, 0, -1.0/2, },
723     { 0, 0, 0, 0, -1, 0, 1.0/2, 0, -1.0/2, },
724     { 1, 0, 0, 0, 1, 0, -1, 0, 0, },
725   },
726 };
727 
728 static int tetra_generators[][3][9] =
729 {
730   { /* 1 */
731     {  0, -1, 0, 1, 0, 0, 0, 0, 1, },
732     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
733     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
734   },
735   { /* 2 */
736     {  0, -1, 0, 1, 0, 0, 0, 0, 1, },
737     {  1, 0, 0, 0, -1, 0, 0, 0, -1, },
738     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
739   },
740   { /* 3 */
741     {  0, -1, 0, 1, 0, 0, 0, 0, 1, },
742     {  -1, 0, 0, 0, 1, 0, 0, 0, 1, },
743     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
744   },
745   { /* 4 */
746     {  0, 1, 0, -1, 0, 0, 0, 0, -1, },
747     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
748     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
749   },
750   { /* 5 */
751     {  0, 1, 0, -1, 0, 0, 0, 0, -1, },
752     {  1, 0, 0, 0, -1, 0, 0, 0, -1, },
753     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
754   },
755   { /* 6 */
756     {  0, 1, 0, -1, 0, 0, 0, 0, -1, },
757     {  -1, 0, 0, 0, 1, 0, 0, 0, 1, },
758     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
759   },
760   { /* 7 */
761     {  0, -1, 0, 1, 0, 0, 0, 0, 1, },
762     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
763     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
764   },
765   { /* 8 */
766     {  0, -1, 0, 1, 0, 0, 0, 0, 1, },
767     {  1, 0, 0, 0, -1, 0, 0, 0, -1, },
768     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
769   },
770 };
771 
772 static double trigo_VSpU[][3][9] =
773 {
774   { /* 1 */
775     { -2.0/3, 1.0/3, 0,  0,  0,  0,  0,  0,  0, },
776     { -1.0/3, -1.0/3, 0,  0,  0,  0,  0,  0,  0, },
777     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
778   },
779   { /* 2 */
780     { 0, 1.0/3, 0, -2.0/3, 0, 0,  0,  0,  0, },
781     { 0, -1.0/3, 0, -1.0/3, 0, 0,  0,  0,  0, },
782     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
783   },
784   { /* 3 */
785     { 0, -1, 0, -2, 0, 0,  0,  0,  0, },
786     { 0, -1, 0, -1, 0, 0,  0,  0,  0, },
787     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
788   },
789   { /* 4 */
790     { 0, -1, 0, -2, 0, 0,  0,  0,  0, },
791     { 0, -1, 0, -1, 0, 0,  0,  0,  0, },
792     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
793   },
794   { /* 5 */
795     { 0, 1.0/3, 0, -2.0/3, 0, 0,  0,  0,  0, },
796     { 0, -1.0/3, 0, -1.0/3, 0, 0,  0,  0,  0, },
797     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
798   },
799   { /* 6 */
800     { 0, -1, 0,  0,  0,  0,  0,  0,  0, },
801     { 1, -1, 0,  0,  0,  0,  0,  0,  0, },
802     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
803   },
804   { /* 7 */
805     { 0, -1, 0, 0, 0, 0,  0,  0,  0, },
806     { 0, 1, 0, -1, 0, 0,  0,  0,  0, },
807     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
808   },
809   { /* 8 */
810     { 0, -1, 0, 0, 0, 0,  0,  0,  0, },
811     { 0, -1, 0, 1, 0, 0,  0,  0,  0, },
812     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
813   },
814   { /* 9 */
815     { 0, -1, 0, 0, 0, 0,  0,  0,  0, },
816     { 0, -1, 0, 1, 0, 0,  0,  0,  0, },
817     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
818   },
819   { /* 10 */
820     { 0, -1, 0, 0, 0, 0,  0,  0,  0, },
821     { 0, 1, 0, -1, 0, 0,  0,  0,  0, },
822     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
823   },
824   { /* 11 */
825     { -6, 3, 0, 4, 0, 0,  0,  0,  0, },
826     { -3, 1, 0, 2, 0, 0,  0,  0,  0, },
827     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
828   },
829   { /* 12 */
830     { 0, 1, 0, -2, 0, 0, 1, 0, 0, },
831     { 0, -1, 0, 1, 0, 0, -1, 0, 0, },
832     { 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, },
833   },
834   { /* 13 */
835     { 0, -1, 0, -2, 0, 0, 0, 0, 0, },
836     { 0, -1, 0, -1, 0, 0, 0, 0, 0, },
837     { 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, },
838   },
839 };
840 
841 static int trigo_generators[][3][9] =
842 {
843   { /* 1 */
844     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
845     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
846     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
847   },
848   { /* 2 */
849     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
850     {  0, -1, 0, -1, 0, 0, 0, 0, -1, },
851     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
852   },
853   { /* 3 */
854     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
855     {  0, 1, 0, 1, 0, 0, 0, 0, -1, },
856     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
857   },
858   { /* 4 */
859     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
860     {  0, 1, 0, 1, 0, 0, 0, 0, 1, },
861     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
862   },
863   { /* 5 */
864     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
865     {  0, -1, 0, -1, 0, 0, 0, 0, 1, },
866     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
867   },
868   { /* 6 */
869     {  0, 1, 0, -1, 1, 0, 0, 0, -1, },
870     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
871     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
872   },
873   { /* 7 */
874     {  0, 1, 0, -1, 1, 0, 0, 0, -1, },
875     {  0, -1, 0, -1, 0, 0, 0, 0, -1, },
876     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
877   },
878   { /* 8 */
879     {  0, 1, 0, -1, 1, 0, 0, 0, -1, },
880     {  0, 1, 0, 1, 0, 0, 0, 0, -1, },
881     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
882   },
883   { /* 9 */
884     {  0, 1, 0, -1, 1, 0, 0, 0, -1, },
885     {  0, 1, 0, 1, 0, 0, 0, 0, 1, },
886     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
887   },
888   { /* 10 */
889     {  0, 1, 0, -1, 1, 0, 0, 0, -1, },
890     {  0, -1, 0, -1, 0, 0, 0, 0, 1, },
891     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
892   },
893   { /* 11 */
894     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
895     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
896     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
897   },
898   { /* 12 */
899     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
900     {  0, -1, 0, -1, 0, 0, 0, 0, -1, },
901     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
902   },
903   { /* 13 */
904     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
905     {  0, 1, 0, 1, 0, 0, 0, 0, -1, },
906     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
907   },
908 };
909 
910 static double rhombo_h_VSpU[][3][9] =
911 {
912   { /* 1 */
913     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
914     { 0, 0, 1,  0,  0,  0,  0,  0,  0, },
915     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
916   },
917   { /* 2 */
918     { -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
919     { -1.0/2, -1, 0, -1.0/2, 0, 0,  0,  0,  0, },
920     { 1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
921   },
922   { /* 3 */
923     { 0, 0, 0, -1, 0, 0,  0,  0,  0, },
924     { 0, -1, 0, -1, 0, 0,  0,  0,  0, },
925     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
926   },
927   { /* 4 */
928     { -1.0/2, -1.0/2, 1.0/2,  0,  0,  0,  0,  0,  0, },
929     { 1.0/2, -1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, },
930     { -1.0/2, 1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, },
931   },
932   { /* 5 */
933     { 0, -1, 0, 0, 1.0/2, 0,  0,  0,  0, },
934     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
935     { 0, 1, 0, -1, -1.0/2, 0,  0,  0,  0, },
936   },
937   { /* 6 */
938     { -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
939     { 1.0/2, -1, 0, 1.0/2, 0, 0,  0,  0,  0, },
940     { -1.0/2, 0, 0, 1.0/2, 0, 0,  0,  0,  0, },
941   },
942   { /* 7 */
943     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
944     { 1, 0, 1, -1.0/2, 0, 0,  0,  0,  0, },
945     { 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
946   },
947   { /* 8 */
948     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
949     { 0, -1, 0, 0, 0, 0, -1.0/2, 0, 0, },
950     { 0, 0, 0, -1, 0, 0, 1.0/2, 0, 0, },
951   },
952 };
953 
954 static int rhombo_h_generators[][3][9] =
955 {
956   { /* 1 */
957     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
958     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
959     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
960   },
961   { /* 2 */
962     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
963     {  0, 1, 0, 1, 0, 0, 0, 0, -1, },
964     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
965   },
966   { /* 3 */
967     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
968     {  0, -1, 0, -1, 0, 0, 0, 0, 1, },
969     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
970   },
971   { /* 4 */
972     {  0, 1, 0, -1, 1, 0, 0, 0, -1, },
973     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
974     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
975   },
976   { /* 5 */
977     {  0, 1, 0, -1, 1, 0, 0, 0, -1, },
978     {  0, 1, 0, 1, 0, 0, 0, 0, -1, },
979     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
980   },
981   { /* 6 */
982     {  0, 1, 0, -1, 1, 0, 0, 0, -1, },
983     {  0, -1, 0, -1, 0, 0, 0, 0, 1, },
984     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
985   },
986   { /* 7 */
987     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
988     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
989     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
990   },
991   { /* 8 */
992     {  0, -1, 0, 1, -1, 0, 0, 0, 1, },
993     {  0, 1, 0, 1, 0, 0, 0, 0, -1, },
994     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
995   },
996 };
997 
998 static double rhombo_p_VSpU[][3][9] =
999 {
1000   { /* 1 */
1001     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
1002     { 0, 0, 1,  0,  0,  0,  0,  0,  0, },
1003     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
1004   },
1005   { /* 2 */
1006     { -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
1007     { -1.0/2, -1, 0, -1.0/2, 0, 0,  0,  0,  0, },
1008     { 1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
1009   },
1010   { /* 3 */
1011     { 0, 0, 0, -1, 0, 0,  0,  0,  0, },
1012     { 0, -1, 0, -1, 0, 0,  0,  0,  0, },
1013     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
1014   },
1015   { /* 4 */
1016     { -1.0/2, -1.0/2, 1.0/2,  0,  0,  0,  0,  0,  0, },
1017     { 1.0/2, -1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, },
1018     { -1.0/2, 1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, },
1019   },
1020   { /* 5 */
1021     { 0, -1, 0, 0, 1.0/2, 0,  0,  0,  0, },
1022     { 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, },
1023     { 0, 1, 0, -1, -1.0/2, 0,  0,  0,  0, },
1024   },
1025   { /* 6 */
1026     { -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
1027     { 1.0/2, -1, 0, 1.0/2, 0, 0,  0,  0,  0, },
1028     { -1.0/2, 0, 0, 1.0/2, 0, 0,  0,  0,  0, },
1029   },
1030   { /* 7 */
1031     { 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
1032     { 1, 0, 1, -1.0/2, 0, 0,  0,  0,  0, },
1033     { 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, },
1034   },
1035   { /* 8 */
1036     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
1037     { 0, -1, 0, 0, 0, 0, -1.0/2, 0, 0, },
1038     { 0, 0, 0, -1, 0, 0, 1.0/2, 0, 0, },
1039   },
1040 };
1041 
1042 static int rhombo_p_generators[][3][9] =
1043 {
1044   { /* 1 */
1045     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1046     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1047     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1048   },
1049   { /* 2 */
1050     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1051     {  0, 0, -1, 0, -1, 0, -1, 0, 0, },
1052     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1053   },
1054   { /* 3 */
1055     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1056     {  0, 0, 1, 0, 1, 0, 1, 0, 0, },
1057     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1058   },
1059   { /* 4 */
1060     {  0, 0, -1, -1, 0, 0, 0, -1, 0, },
1061     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1062     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1063   },
1064   { /* 5 */
1065     {  0, 0, -1, -1, 0, 0, 0, -1, 0, },
1066     {  0, 0, -1, 0, -1, 0, -1, 0, 0, },
1067     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1068   },
1069   { /* 6 */
1070     {  0, 0, -1, -1, 0, 0, 0, -1, 0, },
1071     {  0, 0, 1, 0, 1, 0, 1, 0, 0, },
1072     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1073   },
1074   { /* 7 */
1075     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1076     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
1077     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1078   },
1079   { /* 8 */
1080     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1081     {  0, 0, -1, 0, -1, 0, -1, 0, 0, },
1082     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
1083   },
1084 };
1085 
1086 static double hexa_VSpU[][3][9] =
1087 {
1088   { /* 1 */
1089     { -1, 1, 0,  0,  0,  0,  0,  0,  0, },
1090     { -1, 0, 0,  0,  0,  0,  0,  0,  0, },
1091     { 0, 0, 0,  0,  0,  0,  0,  0,  0, },
1092   },
1093   { /* 2 */
1094     { 1, 0, 0, -1, 0, 0,  0,  0,  0, },
1095     { -1, 0, 0, 0, 0, 0,  0,  0,  0, },
1096     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
1097   },
1098   { /* 3 */
1099     { -1, 0, 0, -1, 0, 0,  0,  0,  0, },
1100     { -1, 0, 0, 0, 0, 0,  0,  0,  0, },
1101     { 0, 0, 0, 0, 0, 0,  0,  0,  0, },
1102   },
1103   { /* 4 */
1104     { -1.0/3, -1.0/3, 0,  0,  0,  0,  0,  0,  0, },
1105     { 1.0/3, -2.0/3, 0,  0,  0,  0,  0,  0,  0, },
1106     { 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, },
1107   },
1108   { /* 5 */
1109     { -1.0/3, 0, 0, -1.0/3, 0, 0,  0,  0,  0, },
1110     { 1.0/3, 0, 0, -2.0/3, 0, 0,  0,  0,  0, },
1111     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
1112   },
1113   { /* 6 */
1114     { -1, 0, 0, 1, 0, 0,  0,  0,  0, },
1115     { -1, 0, 0, 2, 0, 0,  0,  0,  0, },
1116     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
1117   },
1118   { /* 7 */
1119     { -1, 1, 0, 0, 0, 0,  0,  0,  0, },
1120     { -1, 0, 0, 0, 0, 0,  0,  0,  0, },
1121     { 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, },
1122   },
1123   { /* 8 */
1124     { 1, 0, 0, -1, 0, 0, 0, 0, 0, },
1125     { -1, 0, 0, 0, 0, 0, 0, 0, 0, },
1126     { 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, },
1127   },
1128 };
1129 
1130 static int hexa_generators[][3][9] =
1131 {
1132   { /* 1 */
1133     {  1, -1, 0, 1, 0, 0, 0, 0, 1, },
1134     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1135     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1136   },
1137   { /* 2 */
1138     {  1, -1, 0, 1, 0, 0, 0, 0, 1, },
1139     {  0, -1, 0, -1, 0, 0, 0, 0, -1, },
1140     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1141   },
1142   { /* 3 */
1143     {  1, -1, 0, 1, 0, 0, 0, 0, 1, },
1144     {  0, 1, 0, 1, 0, 0, 0, 0, 1, },
1145     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1146   },
1147   { /* 4 */
1148     {  -1, 1, 0, -1, 0, 0, 0, 0, -1, },
1149     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1150     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1151   },
1152   { /* 5 */
1153     {  -1, 1, 0, -1, 0, 0, 0, 0, -1, },
1154     {  0, -1, 0, -1, 0, 0, 0, 0, -1, },
1155     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1156   },
1157   { /* 6 */
1158     {  -1, 1, 0, -1, 0, 0, 0, 0, -1, },
1159     {  0, 1, 0, 1, 0, 0, 0, 0, 1, },
1160     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1161   },
1162   { /* 7 */
1163     {  1, -1, 0, 1, 0, 0, 0, 0, 1, },
1164     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
1165     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1166   },
1167   { /* 8 */
1168     {  1, -1, 0, 1, 0, 0, 0, 0, 1, },
1169     {  0, -1, 0, -1, 0, 0, 0, 0, -1, },
1170     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
1171   },
1172 };
1173 
1174 static double cubic_VSpU[][3][9] =
1175 {
1176   { /* 1 */
1177     { -1.0/2, 1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1178     { -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1179     { -1.0/2, 1.0/2, 0, 1, 0, 0,  0,  0,  0, },
1180   },
1181   { /* 2 */
1182     { -1.0/2, 1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1183     { -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1184     { 1.0/2, -1.0/2, 0, -1, 0, 0,  0,  0,  0, },
1185   },
1186   { /* 3 */
1187     { 0, -1.0/2, 0, -1, 0, -1,  0,  0,  0, },
1188     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1189     { 0, -1.0/2, 0, 0, 0, -1,  0,  0,  0, },
1190   },
1191   { /* 4 */
1192     { 0, -1.0/2, 0, -1, 0, 1,  0,  0,  0, },
1193     { 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1194     { 0, 1.0/2, 0, 0, 0, -1,  0,  0,  0, },
1195   },
1196   { /* 5 */
1197     { -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1198     { 1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1199     { -1.0/2, -1.0/2, 0, 1, 0, 0,  0,  0,  0, },
1200   },
1201   { /* 6 */
1202     { -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1203     { 1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, },
1204     { 1.0/2, 1.0/2, 0, -1, 0, 0,  0,  0,  0, },
1205   },
1206   { /* 7 */
1207     { 0, 0, -1.0/2, -1, 0, 0,  0,  0,  0, },
1208     { 0, 0, -1.0/2, 0, 0, 1,  0,  0,  0, },
1209     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
1210   },
1211   { /* 8 */
1212     { 0, 0, 1.0/2, -1, 0, 0,  0,  0,  0, },
1213     { 0, 0, 1.0/2, 0, 0, -1,  0,  0,  0, },
1214     { 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, },
1215   },
1216   { /* 9 */
1217     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
1218     { 0, -1, 0, 0, 0, 0, -1.0/2, 0, 0, },
1219     { 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, },
1220   },
1221   { /* 10 */
1222     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
1223     { 0, 0, 0, 1, 0, 1, -1.0/2, 0, 0, },
1224     { 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, },
1225   },
1226 };
1227 
1228 static double cubic_F_VSpU[][3][9] =
1229 {
1230   { /* 1 */
1231     { 0, 0, -1.0/2, -1.0/2, 0, 0,  0,  0,  0, },
1232     { 0, -1, 1.0/2, -1.0/2, 0, 0,  0,  0,  0, },
1233     { 0, 0, -1.0/2, 1.0/2, 0, 0,  0,  0,  0, },
1234   },
1235   { /* 2 */
1236     { 0, 1.0/2, -1.0/2, 0, -1.0/2, 0,  0,  0,  0, },
1237     { 0, -1.0/2, 1.0/2, 0, -1.0/2, 0,  0,  0,  0, },
1238     { 0, -1.0/2, -1.0/2, 0, 1.0/2, 0,  0,  0,  0, },
1239   },
1240   { /* 3 */
1241     { 0, 1.0/4, -1.0/4, -1.0/2, 0, 0,  0,  0,  0, },
1242     { 0, -3.0/4, -1.0/4, -1.0/2, 0, 0,  0,  0,  0, },
1243     { 0, 1.0/4, -1.0/4, 1.0/2, 0, 0,  0,  0,  0, },
1244   },
1245   { /* 4 */
1246     { 0, 1.0/2, 0, 0, -1.0/2, 0,  0,  0,  0, },
1247     { 0, -1.0/2, 0, 0, -1.0/2, 0,  0,  0,  0, },
1248     { 0, -1.0/2, 0, -1, 1.0/2, 0,  0,  0,  0, },
1249   },
1250   { /* 5 */
1251     { -1.0/4, 1.0/4, 0, -1.0/2, 0, 0,  0,  0,  0, },
1252     { -1.0/4, -3.0/4, 0, 1.0/2, 0, 0,  0,  0,  0, },
1253     { -1.0/4, 1.0/4, 0, 1.0/2, 0, 0,  0,  0,  0, },
1254   },
1255   { /* 6 */
1256     { 0, 0, 1.0/2, -1.0/2, 0, 0,  0,  0,  0, },
1257     { 0, -1, -1.0/2, -1.0/2, 0, 0,  0,  0,  0, },
1258     { 0, 0, -1.0/2, -1.0/2, 0, 0,  0,  0,  0, },
1259   },
1260   { /* 7 */
1261     { 0, -1.0/2, 0, -1.0/2, 0, -1.0/2,  0,  0,  0, },
1262     { 0, -1.0/2, 0, 1.0/2, 0, 1.0/2,  0,  0,  0, },
1263     { 0, -1.0/2, 0, 1.0/2, 0, -1.0/2,  0,  0,  0, },
1264   },
1265   { /* 8 */
1266     { 0, 0, 1.0/2, -1.0/2, 0, 1.0/2,  0,  0,  0, },
1267     { 0, 0, 1.0/2, 1.0/2, 0, -1.0/2,  0,  0,  0, },
1268     { 0, 0, -1.0/2, -1.0/2, 0, -1.0/2,  0,  0,  0, },
1269   },
1270   { /* 9 */
1271     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
1272     { 0, -1, 0, -1, 0, 0, 1.0/2, 0, 0, },
1273     { 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, },
1274   },
1275   { /* 10 */
1276     { 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, },
1277     { 0, 0, -1, -2, 0, 0, 3.0/2, 0, 0, },
1278     { 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, },
1279   },
1280 };
1281 
1282 static double cubic_I_VSpU[][3][9] =
1283 {
1284   { /* 1 */
1285     { 0, -1, 0, -1, 0, 0,  0,  0,  0, },
1286     { 1, -1, 0, -1, 0, 0,  0,  0,  0, },
1287     { 0, -1, 0, 0, 0, 0,  0,  0,  0, },
1288   },
1289   { /* 2 */
1290     { -1, 0, 1, -1, 0, 0,  0,  0,  0, },
1291     { 0, 0, 1, -1, 0, 0,  0,  0,  0, },
1292     { 1, 0, -1, 0, 0, 0,  0,  0,  0, },
1293   },
1294   { /* 3 */
1295     { 1, 0, -1, -2, 0, -1,  0,  0,  0, },
1296     { 1, 0, -1, -1, 0, 0,  0,  0,  0, },
1297     { 1, 0, -1, -1, 0, -1,  0,  0,  0, },
1298   },
1299   { /* 4 */
1300     { -1, 0, 1, 0, 0, -1,  0,  0,  0, },
1301     { 3, 0, -1, -3, 0, 2,  0,  0,  0, },
1302     { -3, 0, 1, 3, 0, -3,  0,  0,  0, },
1303   },
1304   { /* 5 */
1305     { 1, 2, -5, -7, 0, 0,  0,  0,  0, },
1306     { 1, 1, -4, -5, 0, 0,  0,  0,  0, },
1307     { 0, 1, -2, -2, 0, 0,  0,  0,  0, },
1308   },
1309   { /* 6 */
1310     { -2, 1, 0, 1, 0, 0,  0,  0,  0, },
1311     { 1, -1, 0, -1, 0, 0,  0,  0,  0, },
1312     { 2, -1, 0, -2, 0, 0,  0,  0,  0, },
1313   },
1314   { /* 7 */
1315     { -1, 0, 0, 0, 0, -1,  0,  0,  0, },
1316     { -1, 0, 0, 1, 0, 0,  0,  0,  0, },
1317     { -1, 0, 0, 1, 0, -1,  0,  0,  0, },
1318   },
1319   { /* 8 */
1320     { 1, 0, 0, 0, -2, 1,  0,  0,  0, },
1321     { -1, 0, 0, 0, 1, -1,  0,  0,  0, },
1322     { 1, 0, 0, 0, -1, 0,  0,  0,  0, },
1323   },
1324   { /* 9 */
1325     { -2, -3, 0, -1, 0, 0, 1, -1, 1, },
1326     { -1, -3, 0, -1, 0, 0, 1, -1, 1, },
1327     { 0, -1, 0, 0, 0, 0, 0, 0, 0, },
1328   },
1329   { /* 10 */
1330     { -1, 0, 0, 0, 0, -1, 0, -1, 1, },
1331     { -1, 0, 0, 1, 0, 0, 0, -1, 1, },
1332     { -1, 0, 0, 1, 0, -1, 0, -1, 1, },
1333   },
1334 };
1335 
1336 static int cubic_generators[][3][9] =
1337 {
1338   { /* 1 */
1339     {  0, -1, 0, 1, 0, 0, 0, 0, 1, },
1340     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1341     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1342   },
1343   { /* 2 */
1344     {  0, -1, 0, 1, 0, 0, 0, 0, 1, },
1345     {  0, 0, -1, -1, 0, 0, 0, -1, 0, },
1346     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1347   },
1348   { /* 3 */
1349     {  -1, 0, 0, 0, -1, 0, 0, 0, 1, },
1350     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1351     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1352   },
1353   { /* 4 */
1354     {  -1, 0, 0, 0, -1, 0, 0, 0, 1, },
1355     {  0, 0, -1, -1, 0, 0, 0, -1, 0, },
1356     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1357   },
1358   { /* 5 */
1359     {  0, 1, 0, -1, 0, 0, 0, 0, -1, },
1360     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1361     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1362   },
1363   { /* 6 */
1364     {  0, 1, 0, -1, 0, 0, 0, 0, -1, },
1365     {  0, 0, -1, -1, 0, 0, 0, -1, 0, },
1366     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1367   },
1368   { /* 7 */
1369     {  1, 0, 0, 0, 1, 0, 0, 0, -1, },
1370     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1371     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1372   },
1373   { /* 8 */
1374     {  1, 0, 0, 0, 1, 0, 0, 0, -1, },
1375     {  0, 0, -1, -1, 0, 0, 0, -1, 0, },
1376     {   0,  0,  0,  0,  0,  0,  0,  0,  0, },
1377   },
1378   { /* 9 */
1379     {  0, -1, 0, 1, 0, 0, 0, 0, 1, },
1380     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1381     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
1382   },
1383   { /* 10 */
1384     {  -1, 0, 0, 0, -1, 0, 0, 0, 1, },
1385     {  0, 0, 1, 1, 0, 0, 0, 1, 0, },
1386     {  -1, 0, 0, 0, -1, 0, 0, 0, -1, },
1387   },
1388 };
1389 
1390 
1391 static int find_hall_symbol(double origin_shift[3],
1392                             SPGCONST double bravais_lattice[3][3],
1393                             const int hall_number,
1394                             const Centering centering,
1395                             const Symmetry *symmetry,
1396                             const double symprec);
1397 static int is_hall_symbol(double shift[3],
1398                           const int hall_number,
1399                           SPGCONST double primitive_lattice[3][3],
1400                           const Symmetry *symmetry,
1401                           Centering centering,
1402                           SPGCONST int generators[3][9],
1403                           SPGCONST double VSpU[3][9],
1404                           const double symprec);
1405 static int is_hall_symbol_cubic(double shift[3],
1406                                 const int hall_number,
1407                                 SPGCONST double primitive_lattice[3][3],
1408                                 const Symmetry *symmetry,
1409                                 const Centering centering,
1410                                 const double symprec);
1411 static int is_hall_symbol_hexa(double shift[3],
1412                                const int hall_number,
1413                                SPGCONST double primitive_lattice[3][3],
1414                                const Symmetry *symmetry,
1415                                const double symprec);
1416 static int is_hall_symbol_rhombo(double shift[3],
1417                                  const int hall_number,
1418                                  SPGCONST double primitive_lattice[3][3],
1419                                  const Symmetry *symmetry,
1420                                  const double symprec);
1421 static int is_hall_symbol_trigonal(double shift[3],
1422                                    const int hall_number,
1423                                    SPGCONST double primitive_lattice[3][3],
1424                                    const Symmetry *symmetry,
1425                                    const double symprec);
1426 static int is_hall_symbol_tetra(double shift[3],
1427                                 const int hall_number,
1428                                 SPGCONST double primitive_lattice[3][3],
1429                                 const Symmetry *symmetry,
1430                                 const Centering centering,
1431                                 const double symprec);
1432 static int is_hall_symbol_ortho(double shift[3],
1433                                 const int hall_number,
1434                                 SPGCONST double primitive_lattice[3][3],
1435                                 const Symmetry *symmetry,
1436                                 const Centering centering,
1437                                 const double symprec);
1438 static int is_hall_symbol_monocli(double shift[3],
1439                                   const int hall_number,
1440                                   SPGCONST double primitive_lattice[3][3],
1441                                   const Symmetry *symmetry,
1442                                   const Centering centering,
1443                                   const double symprec);
1444 static int is_hall_symbol_tricli(double shift[3],
1445                                  const int hall_number,
1446                                  SPGCONST double primitive_lattice[3][3],
1447                                  const Symmetry *symmetry,
1448                                  const double symprec);
1449 static int get_translations(double trans[3][3],
1450                             const Symmetry *symmetry,
1451                             SPGCONST int rot[3][3][3]);
1452 static void transform_translation(double trans_reduced[3],
1453                                   const Centering centering,
1454                                   const double trans[3]);
1455 static void transform_rotation(double rot_reduced[3][3],
1456                                const Centering centering,
1457                                SPGCONST int rot[3][3]);
1458 static int get_origin_shift(double shift[3],
1459                             const int hall_number,
1460                             SPGCONST int rot[3][3][3],
1461                             SPGCONST double trans[3][3],
1462                             const Centering centering,
1463                             SPGCONST double VSpU[3][9]);
1464 static void unpack_generators(int rot[3][3][3], int generators[3][9]);
1465 static int set_dw(double dw[3],
1466                   const int operation_index[2],
1467                   SPGCONST int rot[3][3],
1468                   const double trans[3],
1469                   const Centering centering);
1470 static int is_match_database(const int hall_number,
1471                              const double shift[3],
1472                              SPGCONST double primitive_lattice[3][3],
1473                              const Centering centering,
1474                              const Symmetry *symmetry,
1475                              const double symprec);
1476 
1477 
hal_match_hall_symbol_db(double origin_shift[3],SPGCONST double bravais_lattice[3][3],const int hall_number,const Centering centering,const Symmetry * symmetry,const double symprec)1478 int hal_match_hall_symbol_db(double origin_shift[3],
1479                              SPGCONST double bravais_lattice[3][3],
1480                              const int hall_number,
1481                              const Centering centering,
1482                              const Symmetry *symmetry,
1483                              const double symprec)
1484 {
1485   return find_hall_symbol(origin_shift,
1486                           bravais_lattice,
1487                           hall_number,
1488                           centering,
1489                           symmetry,
1490                           symprec);
1491 }
1492 
find_hall_symbol(double origin_shift[3],SPGCONST double bravais_lattice[3][3],const int hall_number,const Centering centering,const Symmetry * symmetry,const double symprec)1493 static int find_hall_symbol(double origin_shift[3],
1494                             SPGCONST double bravais_lattice[3][3],
1495                             const int hall_number,
1496                             const Centering centering,
1497                             const Symmetry *symmetry,
1498                             const double symprec)
1499 {
1500   double primitive_lattice[3][3];
1501 
1502   switch (centering) {
1503   case PRIMITIVE:
1504     mat_copy_matrix_d3(primitive_lattice, bravais_lattice);
1505     break;
1506   case BODY:
1507     mat_multiply_matrix_d3(primitive_lattice, bravais_lattice, M_bcc_inv);
1508     break;
1509   case FACE:
1510     mat_multiply_matrix_d3(primitive_lattice, bravais_lattice, M_fcc_inv);
1511     break;
1512   case A_FACE:
1513     mat_multiply_matrix_d3(primitive_lattice, bravais_lattice, M_ac_inv);
1514     break;
1515   case B_FACE:
1516     mat_multiply_matrix_d3(primitive_lattice, bravais_lattice, M_bc_inv);
1517     break;
1518   case C_FACE:
1519     mat_multiply_matrix_d3(primitive_lattice, bravais_lattice, M_cc_inv);
1520     break;
1521   case R_CENTER:
1522     mat_multiply_matrix_d3(primitive_lattice, bravais_lattice, M_rc_inv);
1523     break;
1524   default:
1525     break;
1526   }
1527 
1528   /* CUBIC IT: 195-230, Hall: 489-530 */
1529   if (489 <= hall_number && hall_number <= 530) {
1530     if (is_hall_symbol_cubic(origin_shift,
1531                              hall_number,
1532                              primitive_lattice,
1533                              symmetry,
1534                              centering,
1535                              symprec)) {goto found;}
1536     return 0;
1537   }
1538 
1539   /* HEXA, IT: 168-194, Hall: 462-488 */
1540   if (462 <= hall_number && hall_number <= 488) {
1541     if (is_hall_symbol_hexa(origin_shift,
1542                             hall_number,
1543                             primitive_lattice,
1544                             symmetry,
1545                             symprec)) {goto found;}
1546     return 0;
1547   }
1548 
1549   /* TRIGO, IT: 143-167, Hall: 430-461 */
1550   if (430 <= hall_number && hall_number <= 461) {
1551     if (hall_number == 433 ||
1552         hall_number == 434 ||
1553         hall_number == 436 ||
1554         hall_number == 437 ||
1555         hall_number == 444 ||
1556         hall_number == 445 ||
1557         hall_number == 450 ||
1558         hall_number == 451 ||
1559         hall_number == 452 ||
1560         hall_number == 453 ||
1561         hall_number == 458 ||
1562         hall_number == 459 ||
1563         hall_number == 460 ||
1564         hall_number == 461) {
1565       if (is_hall_symbol_rhombo(origin_shift,
1566                                 hall_number,
1567                                 primitive_lattice,
1568                                 symmetry,
1569                                 symprec)) {goto found;}
1570     } else {
1571       if (is_hall_symbol_trigonal(origin_shift,
1572                                   hall_number,
1573                                   primitive_lattice,
1574                                   symmetry,
1575                                   symprec)) {goto found;}
1576     }
1577     return 0;
1578   }
1579 
1580   /* TETRA, IT: 75-142, Hall: 349-429 */
1581   if (349 <= hall_number && hall_number <= 429) {
1582     if (is_hall_symbol_tetra(origin_shift,
1583                              hall_number,
1584                              primitive_lattice,
1585                              symmetry,
1586                              centering,
1587                              symprec)) {goto found;}
1588     return 0;
1589   }
1590 
1591   /* ORTHO, IT: 16-74, Hall: 108-348 */
1592   if (108 <= hall_number && hall_number <= 348) {
1593     if (is_hall_symbol_ortho(origin_shift,
1594                              hall_number,
1595                              primitive_lattice,
1596                              symmetry,
1597                              centering,
1598                              symprec)) {goto found;}
1599     return 0;
1600   }
1601 
1602   /* MONOCLI, IT: 3-15, Hall: 3-107 */
1603   if (3 <= hall_number && hall_number <= 107) {
1604     if (is_hall_symbol_monocli(origin_shift,
1605                                hall_number,
1606                                primitive_lattice,
1607                                symmetry,
1608                                centering,
1609                                symprec)) {goto found;}
1610     return 0;
1611   }
1612 
1613   /* TRICLI, IT: 1-2, Hall: 1-2 */
1614   if (1 <= hall_number && hall_number <= 2) {
1615     if (is_hall_symbol_tricli(origin_shift,
1616                               hall_number,
1617                               primitive_lattice,
1618                               symmetry,
1619                               symprec)) {goto found;}
1620     return 0;
1621   }
1622 
1623   return 0;
1624 
1625  found:
1626   switch (centering) {
1627   case PRIMITIVE:
1628     break;
1629   case BODY:
1630     mat_multiply_matrix_vector_d3(origin_shift, M_bcc_inv, origin_shift);
1631     break;
1632   case FACE:
1633     mat_multiply_matrix_vector_d3(origin_shift, M_fcc_inv, origin_shift);
1634     break;
1635   case A_FACE:
1636     mat_multiply_matrix_vector_d3(origin_shift, M_ac_inv, origin_shift);
1637     break;
1638   case B_FACE:
1639     mat_multiply_matrix_vector_d3(origin_shift, M_bc_inv, origin_shift);
1640     break;
1641   case C_FACE:
1642     mat_multiply_matrix_vector_d3(origin_shift, M_cc_inv, origin_shift);
1643     break;
1644   case R_CENTER:
1645     mat_multiply_matrix_vector_d3(origin_shift, M_rc_inv, origin_shift);
1646     break;
1647   default:
1648     break;
1649   }
1650   return 1;
1651 }
1652 
is_hall_symbol_cubic(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,const Centering centering,const double symprec)1653 static int is_hall_symbol_cubic(double shift[3],
1654                                 const int hall_number,
1655                                 SPGCONST double primitive_lattice[3][3],
1656                                 const Symmetry *symmetry,
1657                                 const Centering centering,
1658                                 const double symprec)
1659 {
1660   int i;
1661 
1662   for (i = 0; i < 10; i++) {
1663     if (centering == PRIMITIVE) {
1664       if (is_hall_symbol(shift,
1665                          hall_number,
1666                          primitive_lattice,
1667                          symmetry,
1668                          centering,
1669                          cubic_generators[i],
1670                          cubic_VSpU[i],
1671                          symprec)) {return 1;}
1672     }
1673 
1674     if (centering == BODY) {
1675       if (is_hall_symbol(shift,
1676                          hall_number,
1677                          primitive_lattice,
1678                          symmetry,
1679                          centering,
1680                          cubic_generators[i],
1681                          cubic_I_VSpU[i],
1682                          symprec)) {return 1;}
1683     }
1684 
1685     if (centering == FACE) {
1686       if (is_hall_symbol(shift,
1687                          hall_number,
1688                          primitive_lattice,
1689                          symmetry,
1690                          centering,
1691                          cubic_generators[i],
1692                          cubic_F_VSpU[i],
1693                          symprec)) {return 1;}
1694     }
1695   }
1696 
1697   return 0;
1698 }
1699 
is_hall_symbol_hexa(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,const double symprec)1700 static int is_hall_symbol_hexa(double shift[3],
1701                                const int hall_number,
1702                                SPGCONST double primitive_lattice[3][3],
1703                                const Symmetry *symmetry,
1704                                const double symprec)
1705 {
1706   int i;
1707 
1708   for (i = 0; i < 8; i++) {
1709     if (is_hall_symbol(shift,
1710                        hall_number,
1711                        primitive_lattice,
1712                        symmetry,
1713                        PRIMITIVE,
1714                        hexa_generators[i],
1715                        hexa_VSpU[i],
1716                        symprec)) {return 1;}
1717   }
1718 
1719   return 0;
1720 }
1721 
is_hall_symbol_trigonal(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,const double symprec)1722 static int is_hall_symbol_trigonal(double shift[3],
1723                                    const int hall_number,
1724                                    SPGCONST double primitive_lattice[3][3],
1725                                    const Symmetry *symmetry,
1726                                    const double symprec)
1727 {
1728   int i;
1729 
1730   for (i = 0; i < 13; i++) {
1731     if (is_hall_symbol(shift,
1732                        hall_number,
1733                        primitive_lattice,
1734                        symmetry,
1735                        PRIMITIVE,
1736                        trigo_generators[i],
1737                        trigo_VSpU[i],
1738                        symprec)) {return 1;}
1739   }
1740 
1741   return 0;
1742 }
1743 
is_hall_symbol_rhombo(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,const double symprec)1744 static int is_hall_symbol_rhombo(double shift[3],
1745                                  const int hall_number,
1746                                  SPGCONST double primitive_lattice[3][3],
1747                                  const Symmetry *symmetry,
1748                                  const double symprec)
1749 {
1750   int i;
1751 
1752   if (hall_number == 433 ||
1753       hall_number == 436 ||
1754       hall_number == 444 ||
1755       hall_number == 450 ||
1756       hall_number == 452 ||
1757       hall_number == 458 ||
1758       hall_number == 460) {
1759     /* hP */
1760     for (i = 0; i < 8; i++) {
1761       if (is_hall_symbol(shift,
1762                          hall_number,
1763                          primitive_lattice,
1764                          symmetry,
1765                          R_CENTER,
1766                          rhombo_h_generators[i],
1767                          rhombo_h_VSpU[i],
1768                          symprec)) {return 1;}
1769     }
1770   } else {
1771     /* hR */
1772     for (i = 0; i < 8; i++) {
1773       if (is_hall_symbol(shift,
1774                          hall_number,
1775                          primitive_lattice,
1776                          symmetry,
1777                          PRIMITIVE,
1778                          rhombo_p_generators[i],
1779                          rhombo_p_VSpU[i],
1780                          symprec)) {return 1;}
1781     }
1782   }
1783 
1784   return 0;
1785 }
1786 
is_hall_symbol_tetra(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,const Centering centering,const double symprec)1787 static int is_hall_symbol_tetra(double shift[3],
1788                                 const int hall_number,
1789                                 SPGCONST double primitive_lattice[3][3],
1790                                 const Symmetry *symmetry,
1791                                 const Centering centering,
1792                                 const double symprec)
1793 {
1794   int i;
1795 
1796   for (i = 0; i < 8; i++) {
1797     if (centering==PRIMITIVE) {
1798       if (is_hall_symbol(shift,
1799                          hall_number,
1800                          primitive_lattice,
1801                          symmetry,
1802                          centering,
1803                          tetra_generators[i],
1804                          tetra_VSpU[i],
1805                          symprec)) {return 1;}
1806     }
1807 
1808     if (centering==BODY) {
1809       if (is_hall_symbol(shift,
1810                          hall_number,
1811                          primitive_lattice,
1812                          symmetry,
1813                          centering,
1814                          tetra_generators[i],
1815                          tetra_I_VSpU[i],
1816                          symprec)) {return 1;}
1817     }
1818   }
1819 
1820   return 0;
1821 }
1822 
is_hall_symbol_ortho(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,const Centering centering,const double symprec)1823 static int is_hall_symbol_ortho(double shift[3],
1824                                 const int hall_number,
1825                                 SPGCONST double primitive_lattice[3][3],
1826                                 const Symmetry *symmetry,
1827                                 const Centering centering,
1828                                 const double symprec)
1829 {
1830   int i;
1831 
1832   for (i = 0; i < 5; i++) {
1833     if (centering == PRIMITIVE) {
1834       if (is_hall_symbol(shift,
1835                          hall_number,
1836                          primitive_lattice,
1837                          symmetry,
1838                          centering,
1839                          ortho_generators[i],
1840                          ortho_VSpU[i],
1841                          symprec)) {return 1;}
1842     }
1843 
1844     if (centering == BODY) {
1845       if (is_hall_symbol(shift,
1846                          hall_number,
1847                          primitive_lattice,
1848                          symmetry,
1849                          centering,
1850                          ortho_generators[i],
1851                          ortho_I_VSpU[i],
1852                          symprec)) {return 1;}
1853     }
1854 
1855     if (centering == FACE) {
1856       if (is_hall_symbol(shift,
1857                          hall_number,
1858                          primitive_lattice,
1859                          symmetry,
1860                          centering,
1861                          ortho_generators[i],
1862                          ortho_F_VSpU[i],
1863                          symprec)) {return 1;}
1864     }
1865 
1866     if (centering == A_FACE) {
1867       if (is_hall_symbol(shift,
1868                          hall_number,
1869                          primitive_lattice,
1870                          symmetry,
1871                          centering,
1872                          ortho_generators[i],
1873                          ortho_A_VSpU[i],
1874                          symprec)) {return 1;}
1875     }
1876 
1877     if (centering == B_FACE) {
1878       if (is_hall_symbol(shift,
1879                          hall_number,
1880                          primitive_lattice,
1881                          symmetry,
1882                          centering,
1883                          ortho_generators[i],
1884                          ortho_B_VSpU[i],
1885                          symprec)) {return 1;}
1886     }
1887 
1888     if (centering == C_FACE) {
1889       if (is_hall_symbol(shift,
1890                          hall_number,
1891                          primitive_lattice,
1892                          symmetry,
1893                          centering,
1894                          ortho_generators[i],
1895                          ortho_C_VSpU[i],
1896                          symprec)) {return 1;}
1897     }
1898   }
1899 
1900   return 0;
1901 }
1902 
is_hall_symbol_monocli(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,const Centering centering,const double symprec)1903 static int is_hall_symbol_monocli(double shift[3],
1904                                   const int hall_number,
1905                                   SPGCONST double primitive_lattice[3][3],
1906                                   const Symmetry *symmetry,
1907                                   const Centering centering,
1908                                   const double symprec)
1909 {
1910   int i;
1911 
1912   for (i = 0; i < 9; i++) {
1913     if (centering == PRIMITIVE) {
1914       if (is_hall_symbol(shift,
1915                          hall_number,
1916                          primitive_lattice,
1917                          symmetry,
1918                          centering,
1919                          monocli_generators[i],
1920                          monocli_VSpU[i],
1921                          symprec)) {return 1;}
1922     }
1923 
1924     if (centering == A_FACE) {
1925       if (is_hall_symbol(shift,
1926                          hall_number,
1927                          primitive_lattice,
1928                          symmetry,
1929                          centering,
1930                          monocli_generators[i],
1931                          monocli_A_VSpU[i],
1932                          symprec)) {return 1;}
1933     }
1934 
1935     if (centering == B_FACE) {
1936       if (is_hall_symbol(shift,
1937                          hall_number,
1938                          primitive_lattice,
1939                          symmetry,
1940                          centering,
1941                          monocli_generators[i],
1942                          monocli_B_VSpU[i],
1943                          symprec)) {return 1;}
1944     }
1945 
1946     if (centering == C_FACE) {
1947       if (is_hall_symbol(shift,
1948                          hall_number,
1949                          primitive_lattice,
1950                          symmetry,
1951                          centering,
1952                          monocli_generators[i],
1953                          monocli_C_VSpU[i],
1954                          symprec)) {return 1;}
1955     }
1956 
1957     if (centering == BODY) {
1958       if (is_hall_symbol(shift,
1959                          hall_number,
1960                          primitive_lattice,
1961                          symmetry,
1962                          centering,
1963                          monocli_generators[i],
1964                          monocli_I_VSpU[i],
1965                          symprec)) {return 1;}
1966     }
1967   }
1968 
1969   return 0;
1970 }
1971 
is_hall_symbol_tricli(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,const double symprec)1972 static int is_hall_symbol_tricli(double shift[3],
1973                                  const int hall_number,
1974                                  SPGCONST double primitive_lattice[3][3],
1975                                  const Symmetry *symmetry,
1976                                  const double symprec)
1977 {
1978   int i;
1979 
1980   for (i = 0; i < 2; i++) {
1981     if (is_hall_symbol(shift,
1982                        hall_number,
1983                        primitive_lattice,
1984                        symmetry,
1985                        PRIMITIVE,
1986                        tricli_generators[i],
1987                        tricli_VSpU[i],
1988                        symprec)) {return 1;}
1989   }
1990 
1991   return 0;
1992 }
1993 
unpack_generators(int rot[3][3][3],int generators[3][9])1994 static void unpack_generators(int rot[3][3][3], int generators[3][9])
1995 {
1996   int i, j, k;
1997   for (i = 0; i < 3; i++) {
1998     for (j = 0; j < 3; j++) {
1999       for (k = 0; k < 3; k++) {
2000         rot[i][j][k] = generators[i][j*3+k];
2001       }
2002     }
2003   }
2004 }
2005 
is_hall_symbol(double shift[3],const int hall_number,SPGCONST double primitive_lattice[3][3],const Symmetry * symmetry,Centering centering,SPGCONST int generators[3][9],SPGCONST double VSpU[3][9],const double symprec)2006 static int is_hall_symbol(double shift[3],
2007                           const int hall_number,
2008                           SPGCONST double primitive_lattice[3][3],
2009                           const Symmetry *symmetry,
2010                           Centering centering,
2011                           SPGCONST int generators[3][9],
2012                           SPGCONST double VSpU[3][9],
2013                           const double symprec)
2014 {
2015   int is_origin_shift;
2016   int operation_index[2];
2017   int rot[3][3][3];
2018   double trans[3][3];
2019 
2020   spgdb_get_operation_index(operation_index, hall_number);
2021 
2022   if (! (operation_index[0] == symmetry->size)) {
2023     goto not_found;
2024   }
2025 
2026   unpack_generators(rot, generators);
2027   if (get_translations(trans, symmetry, rot)) {
2028     is_origin_shift = get_origin_shift(shift,
2029                                        hall_number,
2030                                        rot,
2031                                        trans,
2032                                        centering,
2033                                        VSpU);
2034 
2035     if (is_origin_shift) {
2036       if (is_match_database(hall_number,
2037                             shift,
2038                             primitive_lattice,
2039                             centering,
2040                             symmetry,
2041                             symprec)) {goto found;}
2042     }
2043   } else {
2044     goto not_found;
2045   }
2046 
2047  not_found:
2048   return 0;
2049 
2050  found:
2051   return 1;
2052 }
2053 
get_translations(double trans[3][3],const Symmetry * symmetry,SPGCONST int rot[3][3][3])2054 static int get_translations(double trans[3][3],
2055                             const Symmetry *symmetry,
2056                             SPGCONST int rot[3][3][3])
2057 {
2058   int i, j;
2059   int is_found;
2060   static SPGCONST int zero[3][3] = { { 0, 0, 0 },
2061                                      { 0, 0, 0 },
2062                                      { 0, 0, 0 }, };
2063 
2064   for (i = 0; i < 3; i++) {
2065     for (j = 0; j < 3; j++) {
2066       trans[i][j] = 0;
2067     }
2068   }
2069 
2070   for (i = 0; i < 3; i++) {
2071     if (mat_check_identity_matrix_i3(rot[i], zero)) { continue; }
2072     is_found = 0;
2073     for (j = 0; j < symmetry->size; j++) {
2074       if (mat_check_identity_matrix_i3(symmetry->rot[j], rot[i])) {
2075         mat_copy_vector_d3(trans[i], symmetry->trans[j]);
2076         is_found = 1;
2077         break;
2078       }
2079     }
2080     if (! is_found) {
2081       goto not_found;
2082     }
2083   }
2084 
2085   return 1;
2086 
2087  not_found:
2088 
2089   return 0;
2090 }
2091 
transform_translation(double trans_reduced[3],const Centering centering,const double trans[3])2092 static void transform_translation(double trans_reduced[3],
2093                                   const Centering centering,
2094                                   const double trans[3])
2095 {
2096   int i;
2097 
2098   switch (centering) {
2099   case PRIMITIVE:
2100     mat_copy_vector_d3(trans_reduced, trans);
2101     break;
2102   case BODY:
2103     mat_multiply_matrix_vector_id3(trans_reduced, M_bcc, trans);
2104     break;
2105   case FACE:
2106     mat_multiply_matrix_vector_id3(trans_reduced, M_fcc, trans);
2107     break;
2108   case A_FACE:
2109     mat_multiply_matrix_vector_id3(trans_reduced, M_ac, trans);
2110     break;
2111   case B_FACE:
2112     mat_multiply_matrix_vector_id3(trans_reduced, M_bc, trans);
2113     break;
2114   case C_FACE:
2115     mat_multiply_matrix_vector_id3(trans_reduced, M_cc, trans);
2116     break;
2117   case R_CENTER:
2118     mat_multiply_matrix_vector_id3(trans_reduced, M_rc, trans);
2119     break;
2120   default:
2121     break;
2122   }
2123 
2124   for (i = 0; i < 3; i++) {
2125     trans_reduced[i] = mat_Dmod1(trans_reduced[i]);
2126   }
2127 }
2128 
transform_rotation(double rot_reduced[3][3],const Centering centering,SPGCONST int rot[3][3])2129 static void transform_rotation(double rot_reduced[3][3],
2130                                const Centering centering,
2131                                SPGCONST int rot[3][3])
2132 {
2133   mat_cast_matrix_3i_to_3d(rot_reduced, rot);
2134   if (centering != PRIMITIVE) {
2135     switch (centering) {
2136     case BODY:
2137       mat_get_similar_matrix_d3(rot_reduced, rot_reduced, M_bcc_inv, 0);
2138       break;
2139     case FACE:
2140       mat_get_similar_matrix_d3(rot_reduced, rot_reduced, M_fcc_inv, 0);
2141       break;
2142     case A_FACE:
2143       mat_get_similar_matrix_d3(rot_reduced, rot_reduced, M_ac_inv, 0);
2144       break;
2145     case B_FACE:
2146       mat_get_similar_matrix_d3(rot_reduced, rot_reduced, M_bc_inv, 0);
2147       break;
2148     case C_FACE:
2149       mat_get_similar_matrix_d3(rot_reduced, rot_reduced, M_cc_inv, 0);
2150       break;
2151     case R_CENTER:
2152       mat_get_similar_matrix_d3(rot_reduced, rot_reduced, M_rc_inv, 0);
2153       break;
2154     default:
2155       break;
2156     }
2157   }
2158 }
2159 
get_origin_shift(double shift[3],const int hall_number,SPGCONST int rot[3][3][3],SPGCONST double trans[3][3],const Centering centering,SPGCONST double VSpU[3][9])2160 static int get_origin_shift(double shift[3],
2161                             const int hall_number,
2162                             SPGCONST int rot[3][3][3],
2163                             SPGCONST double trans[3][3],
2164                             const Centering centering,
2165                             SPGCONST double VSpU[3][9])
2166 {
2167   int i, j;
2168   int operation_index[2];
2169   double dw[9], tmp_dw[3];
2170 
2171   spgdb_get_operation_index(operation_index, hall_number);
2172 
2173   /* The obtained dw is reduced to that of primitve cell by centerings. */
2174   for (i = 0; i < 3; i++) {
2175     /* Zero matrix is the sign to set dw 0 */
2176     if (mat_get_determinant_i3(rot[i]) == 0) {
2177       for (j = 0; j < 3; j++) {
2178         dw[i * 3 + j] = 0;
2179       }
2180     } else {
2181       if (set_dw(tmp_dw, operation_index, rot[i], trans[i], centering)) {
2182         for (j = 0; j < 3; j++) {
2183           dw[i * 3 + j] = tmp_dw[j];
2184         }
2185       } else {
2186         goto not_found;
2187       }
2188     }
2189   }
2190 
2191   /* VSpU*dw is given for the primitive cell if there is centering. */
2192   for (i = 0; i < 3; i++) {
2193     shift[i] = 0;
2194     for (j = 0; j < 9; j++) {
2195       shift[i] += VSpU[i][j] * dw[j];
2196     }
2197     shift[i] = mat_Dmod1(shift[i]);
2198   }
2199 
2200   return 1;
2201 
2202  not_found:
2203   return 0;
2204 }
2205 
set_dw(double dw[3],const int operation_index[2],SPGCONST int rot[3][3],const double trans[3],const Centering centering)2206 static int set_dw(double dw[3],
2207                   const int operation_index[2],
2208                   SPGCONST int rot[3][3],
2209                   const double trans[3],
2210                   const Centering centering)
2211 {
2212   int i, j;
2213   int rot_db[3][3];
2214   double trans_db[3], trans_prim[3], trans_db_prim[3];
2215 
2216   transform_translation(trans_prim, centering, trans);
2217   for (i = 0; i < operation_index[0]; i++) {
2218     spgdb_get_operation(rot_db, trans_db, operation_index[1] + i);
2219     transform_translation(trans_db_prim, centering, trans_db);
2220     if (mat_check_identity_matrix_i3(rot_db, rot)) {
2221       for (j = 0; j < 3; j++) {
2222         dw[j] = trans_prim[j] - trans_db_prim[j];
2223         dw[j] = mat_Dmod1(dw[j]);
2224       }
2225       goto found;
2226     }
2227   }
2228 
2229   /* Not found */
2230   return 0;
2231 
2232  found:
2233   return 1;
2234 }
2235 
is_match_database(const int hall_number,const double origin_shift[3],SPGCONST double primitive_lattice[3][3],const Centering centering,const Symmetry * symmetry,const double symprec)2236 static int is_match_database(const int hall_number,
2237                              const double origin_shift[3],
2238                              SPGCONST double primitive_lattice[3][3],
2239                              const Centering centering,
2240                              const Symmetry *symmetry,
2241                              const double symprec)
2242 {
2243   int i, j, k, is_found;
2244   int operation_index[2];
2245   int rot_db[3][3];
2246   int found_list[192];
2247   double trans_db[3], trans_db_prim[3], trans_prim[3], diff[3], shift_rot[3];
2248   double rot_prim[3][3];
2249 
2250   spgdb_get_operation_index(operation_index, hall_number);
2251 
2252   for (i = 0; i < symmetry->size; i++) {found_list[i] = 0;}
2253   for (i = 0; i < symmetry->size; i++) {
2254     is_found = 0;
2255     for (j = 0; j < operation_index[0]; j++) {
2256       spgdb_get_operation(rot_db, trans_db, operation_index[1] + j);
2257       if (mat_check_identity_matrix_i3(symmetry->rot[i], rot_db)) {
2258         transform_translation(trans_db_prim, centering, trans_db);
2259         transform_translation(trans_prim, centering, symmetry->trans[i]);
2260         transform_rotation(rot_prim, centering, rot_db);
2261         for (k = 0; k < 3; k++) {
2262           diff[k] = trans_prim[k] - trans_db_prim[k] + origin_shift[k];
2263         }
2264         mat_multiply_matrix_vector_d3(shift_rot, rot_prim, origin_shift);
2265         if (cel_is_overlap(diff, shift_rot, primitive_lattice, symprec)) {
2266           if (! found_list[j]) {
2267             found_list[j] = 1;
2268             is_found = 1;
2269             break;
2270           }
2271         }
2272       }
2273     }
2274 
2275     if (! is_found) {
2276       goto not_found;
2277     }
2278   }
2279 
2280   return 1;
2281 
2282  not_found:
2283   return 0;
2284 }
2285