Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scipy/spatial/transform/_rotation_groups.py: 14%

56 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-12 06:31 +0000

1import numpy as np 

2from scipy.constants import golden as phi 

3 

4 

5def icosahedral(cls): 

6 g1 = tetrahedral(cls).as_quat() 

7 a = 0.5 

8 b = 0.5 / phi 

9 c = phi / 2 

10 g2 = np.array([[+a, +b, +c, 0], 

11 [+a, +b, -c, 0], 

12 [+a, +c, 0, +b], 

13 [+a, +c, 0, -b], 

14 [+a, -b, +c, 0], 

15 [+a, -b, -c, 0], 

16 [+a, -c, 0, +b], 

17 [+a, -c, 0, -b], 

18 [+a, 0, +b, +c], 

19 [+a, 0, +b, -c], 

20 [+a, 0, -b, +c], 

21 [+a, 0, -b, -c], 

22 [+b, +a, 0, +c], 

23 [+b, +a, 0, -c], 

24 [+b, +c, +a, 0], 

25 [+b, +c, -a, 0], 

26 [+b, -a, 0, +c], 

27 [+b, -a, 0, -c], 

28 [+b, -c, +a, 0], 

29 [+b, -c, -a, 0], 

30 [+b, 0, +c, +a], 

31 [+b, 0, +c, -a], 

32 [+b, 0, -c, +a], 

33 [+b, 0, -c, -a], 

34 [+c, +a, +b, 0], 

35 [+c, +a, -b, 0], 

36 [+c, +b, 0, +a], 

37 [+c, +b, 0, -a], 

38 [+c, -a, +b, 0], 

39 [+c, -a, -b, 0], 

40 [+c, -b, 0, +a], 

41 [+c, -b, 0, -a], 

42 [+c, 0, +a, +b], 

43 [+c, 0, +a, -b], 

44 [+c, 0, -a, +b], 

45 [+c, 0, -a, -b], 

46 [0, +a, +c, +b], 

47 [0, +a, +c, -b], 

48 [0, +a, -c, +b], 

49 [0, +a, -c, -b], 

50 [0, +b, +a, +c], 

51 [0, +b, +a, -c], 

52 [0, +b, -a, +c], 

53 [0, +b, -a, -c], 

54 [0, +c, +b, +a], 

55 [0, +c, +b, -a], 

56 [0, +c, -b, +a], 

57 [0, +c, -b, -a]]) 

58 return cls.from_quat(np.concatenate((g1, g2))) 

59 

60 

61def octahedral(cls): 

62 g1 = tetrahedral(cls).as_quat() 

63 c = np.sqrt(2) / 2 

64 g2 = np.array([[+c, 0, 0, +c], 

65 [0, +c, 0, +c], 

66 [0, 0, +c, +c], 

67 [0, 0, -c, +c], 

68 [0, -c, 0, +c], 

69 [-c, 0, 0, +c], 

70 [0, +c, +c, 0], 

71 [0, -c, +c, 0], 

72 [+c, 0, +c, 0], 

73 [-c, 0, +c, 0], 

74 [+c, +c, 0, 0], 

75 [-c, +c, 0, 0]]) 

76 return cls.from_quat(np.concatenate((g1, g2))) 

77 

78 

79def tetrahedral(cls): 

80 g1 = np.eye(4) 

81 c = 0.5 

82 g2 = np.array([[c, -c, -c, +c], 

83 [c, -c, +c, +c], 

84 [c, +c, -c, +c], 

85 [c, +c, +c, +c], 

86 [c, -c, -c, -c], 

87 [c, -c, +c, -c], 

88 [c, +c, -c, -c], 

89 [c, +c, +c, -c]]) 

90 return cls.from_quat(np.concatenate((g1, g2))) 

91 

92 

93def dicyclic(cls, n, axis=2): 

94 g1 = cyclic(cls, n, axis).as_rotvec() 

95 

96 thetas = np.linspace(0, np.pi, n, endpoint=False) 

97 rv = np.pi * np.vstack([np.zeros(n), np.cos(thetas), np.sin(thetas)]).T 

98 g2 = np.roll(rv, axis, axis=1) 

99 return cls.from_rotvec(np.concatenate((g1, g2))) 

100 

101 

102def cyclic(cls, n, axis=2): 

103 thetas = np.linspace(0, 2 * np.pi, n, endpoint=False) 

104 rv = np.vstack([thetas, np.zeros(n), np.zeros(n)]).T 

105 return cls.from_rotvec(np.roll(rv, axis, axis=1)) 

106 

107 

108def create_group(cls, group, axis='Z'): 

109 if not isinstance(group, str): 

110 raise ValueError("`group` argument must be a string") 

111 

112 permitted_axes = ['x', 'y', 'z', 'X', 'Y', 'Z'] 

113 if axis not in permitted_axes: 

114 raise ValueError("`axis` must be one of " + ", ".join(permitted_axes)) 

115 

116 if group in ['I', 'O', 'T']: 

117 symbol = group 

118 order = 1 

119 elif group[:1] in ['C', 'D'] and group[1:].isdigit(): 

120 symbol = group[:1] 

121 order = int(group[1:]) 

122 else: 

123 raise ValueError("`group` must be one of 'I', 'O', 'T', 'Dn', 'Cn'") 

124 

125 if order < 1: 

126 raise ValueError("Group order must be positive") 

127 

128 axis = 'xyz'.index(axis.lower()) 

129 if symbol == 'I': 

130 return icosahedral(cls) 

131 elif symbol == 'O': 

132 return octahedral(cls) 

133 elif symbol == 'T': 

134 return tetrahedral(cls) 

135 elif symbol == 'D': 

136 return dicyclic(cls, order, axis=axis) 

137 elif symbol == 'C': 

138 return cyclic(cls, order, axis=axis) 

139 else: 

140 assert False