teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

2018/10/17 05:58

投稿

tiitoi
tiitoi

スコア21960

answer CHANGED
@@ -93,10 +93,108 @@
93
93
  S_pad = np.pad(S, (1, 1), 'wrap')
94
94
  print(S_pad)
95
95
 
96
- for i, j in np.dstack(np.mgrid[1:Nx, 1:Ny]).reshape(-1, 2):
96
+ for i, j in np.dstack(np.mgrid[1:Nx+1, 1:Ny+1]).reshape(-1, 2):
97
97
  E[i - 1, j - 1] = -np.cos(S_pad[i, j] - S_pad[i - 1, j]) \
98
98
  - np.cos(S_pad[i, j] - S_pad[i + 1, j]) \
99
99
  - np.cos(S_pad[i, j] - S_pad[i, j + 1]) \
100
100
  - np.cos(S_pad[i, j] - S_pad[i, j - 1])
101
101
  print(E)
102
+ ```
103
+
104
+ ## 追記
105
+
106
+ 話を簡単にするため (3, 3) 行列で考えます。
107
+
108
+ ```python
109
+ Nx, Ny = 3, 3
110
+ S = np.random.randint(0, 5, (Nx, Ny))
111
+ print(S)
112
+ # [[0 2 4]
113
+ # [0 0 3]
114
+ # [2 0 2]]
115
+ ```
116
+
117
+ S_pad は (Nx, Ny) の配列の周囲に1ずつパディングを入れたものです。
118
+ パディングの値は padding='wrap' を指定することで、例えば、S[0, 0] であれば、S[2, 2] の値になるようにしています。
119
+ これにより、E[0, 0] = -cos(S[0, 0] - S[-1, 0]) を計算する場合、条件分岐が不要になります。
120
+
121
+ ```python
122
+ S_pad = np.pad(a, (1, 1), 'wrap')
123
+ print(S_pad)
124
+ # [[2 2 0 2 2]
125
+ # [4 0 2 4 0]
126
+ # [3 0 0 3 0]
127
+ # [2 2 0 2 2]
128
+ # [4 0 2 4 0]]
129
+ ```
130
+
131
+ S_pad の各要素のインデックスは以下のようになっています。
132
+
133
+ ```python
134
+ (0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4)
135
+ (0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4)
136
+ (0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4)
137
+ (0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4)
138
+ (0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4)
139
+ (0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4)
140
+ (0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4)
141
+ ```
142
+
143
+ このうち、元の行列 S の値がある以下のインデックスだけ iterate したいわけです。
144
+
145
+ ```python
146
+ (1, 4) (2, 4) (3, 4) (4, 4) (5, 4)
147
+ (1, 4) (2, 4) (3, 4) (4, 4) (5, 4)
148
+ (1, 4) (2, 4) (3, 4) (4, 4) (5, 4)
149
+ (1, 4) (2, 4) (3, 4) (4, 4) (5, 4)
150
+ (1, 4) (2, 4) (3, 4) (4, 4) (5, 4)
151
+ ```
152
+
153
+ なので、目標は以下の配列を作ることです。
154
+
155
+ ```
156
+ [(1, 1), (1, 2), (1, 3), (1, 4), ...]
157
+ ```
158
+
159
+ np.mgrid は返り値として次の2つの値を返します。
160
+
161
+ ```python
162
+ X, Y = np.mgrid[1:Nx + 1, 1:Ny + 1]
163
+ print(X)
164
+ # 各要素の行
165
+ # [[1 1 1]
166
+ # [2 2 2]
167
+ # [3 3 3]]
168
+
169
+ # 各要素の列
170
+ print(Y)
171
+ # [[1 2 3]
172
+ # [1 2 3]
173
+ # [1 2 3]]
174
+ ```
175
+
176
+ よって、これを np.dstack() で結合すると、各要素のインデックスの一覧が作れます。
177
+
178
+ ```python
179
+ XY = np.dstack([X, Y])
180
+ print(XY)
181
+ # [[[1 1] [1 2] [1 3]]
182
+ # [[2 1] [2 2] [2 3]]
183
+ # [[3 1] [3 2] [3 3]]]
184
+ ```
185
+
186
+ これは (3, 3, 2) の numpy 配列なので、(9, 2) として、reshape() します。
187
+ (3, 3, 2) を (9, 2) に reshape() する際に、(?, 2) と2が決まっていれば、? の部分は9と確定するので、この場合、-1 と指定しておくことができます。
188
+
189
+ ```python
190
+ print(XY.reshape(-1, 2)) # XY.reshape(9, 2) と一緒
191
+ # [[1 1]
192
+ # [1 2]
193
+ # [1 3]
194
+ # [2 1]
195
+ # [2 2]
196
+ # [2 3]
197
+ # [3 1]
198
+ # [3 2]
199
+ # [3 3]]
102
200
  ```

2

a

2018/10/17 05:58

投稿

tiitoi
tiitoi

スコア21960

answer CHANGED
@@ -53,4 +53,50 @@
53
53
  [1 8]
54
54
  [2 1]
55
55
  ...
56
+ ```
57
+
58
+ ## 追記
59
+
60
+ 境界条件って端の場合は反対側の値を使うということですよね。
61
+ であれば、padding='wrap' で [np.pad()](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.pad.html) しておけばいいです。
62
+
63
+ どういうことかは以下を見ていただければわかるかと思います。
64
+
65
+ ```
66
+ a = np.random.randint(0, 5, (5, 5))
67
+ print(a)
68
+ # [[3 3 2 2 0]
69
+ # [0 4 1 2 1]
70
+ # [1 4 4 1 4]
71
+ # [4 4 2 4 0]
72
+ # [4 1 4 3 3]]
73
+
74
+ b = np.pad(a, (1, 1), 'wrap')
75
+ print(b)
76
+ # [[3 4 1 4 3 3 4]
77
+ # [0 3 3 2 2 0 3]
78
+ # [1 0 4 1 2 1 0]
79
+ # [4 1 4 4 1 4 1]
80
+ # [0 4 4 2 4 0 4]
81
+ # [3 4 1 4 3 3 4]
82
+ # [0 3 3 2 2 0 3]]
83
+ ```
84
+
85
+ ```python
86
+ np.set_printoptions(linewidth=120)
87
+
88
+ Nx, Ny = 5, 5
89
+ S = np.random.uniform(0, 2 * np.pi, (5, 5))
90
+ print(S)
91
+
92
+ E = np.empty_like(S)
93
+ S_pad = np.pad(S, (1, 1), 'wrap')
94
+ print(S_pad)
95
+
96
+ for i, j in np.dstack(np.mgrid[1:Nx, 1:Ny]).reshape(-1, 2):
97
+ E[i - 1, j - 1] = -np.cos(S_pad[i, j] - S_pad[i - 1, j]) \
98
+ - np.cos(S_pad[i, j] - S_pad[i + 1, j]) \
99
+ - np.cos(S_pad[i, j] - S_pad[i, j + 1]) \
100
+ - np.cos(S_pad[i, j] - S_pad[i, j - 1])
101
+ print(E)
56
102
  ```

1

a

2018/10/17 05:05

投稿

tiitoi
tiitoi

スコア21960

answer CHANGED
@@ -10,4 +10,47 @@
10
10
  np.dstack([Nx,Ny])
11
11
  ```
12
12
 
13
- とするよう書いてあります。
13
+ とするよう書いてあります。
14
+
15
+ ## 追記
16
+
17
+ 前回の回答で dstack() を使用したのは、「各要素をナンバリングした行列を作りたい」と書いてあったので、np.mgrid で各要素の x 座標と y 座標の一覧を作成し、それを結合するために使いました。
18
+
19
+ ```
20
+ indices = np.dstack(np.mgrid[1:9, 1:9]).reshape(-1, 2)
21
+ print(indices)
22
+ ```
23
+
24
+ ```
25
+ [[1 1]
26
+ [1 2]
27
+ [1 3]
28
+ [1 4]
29
+ [1 5]
30
+ [1 6]
31
+ [1 7]
32
+ ...
33
+ ```
34
+
35
+ ただ、各要素を iteratate するのが目的だったのであれば、np.ndenumerate() を使ったほうがシンプルです。
36
+
37
+ ```python
38
+ a = np.random.randn(5, 5)
39
+ print(a)
40
+
41
+ for index, value in np.ndenumerate(a):
42
+ print(index, value)
43
+ ```
44
+
45
+ ```
46
+ [[1 1]
47
+ [1 2]
48
+ [1 3]
49
+ [1 4]
50
+ [1 5]
51
+ [1 6]
52
+ [1 7]
53
+ [1 8]
54
+ [2 1]
55
+ ...
56
+ ```