@@ -122,17 +122,12 @@ def _vf_ground_sky_2d(x, rotation, gcr, pitch, height, max_rows=10):
122
122
vf : array
123
123
Fraction of sky dome visible from each point on the ground.
124
124
Shape is (len(x), len(rotation)). [unitless]
125
- wedge_angles : array
126
- Angles defining each wedge of sky that is blocked by a row. Shape is
127
- (2, len(x), len(rotation), 2*max_rows+1). ``wedge_angles[0,:,:,:]``
128
- is the starting angle of each wedge, ``wedge_angles[1,:,:,:]`` is the
129
- end angle. [degree]
130
125
"""
131
126
# This function creates large float64 arrays of size
132
127
# (2*len(x)*len(rotation)*len(max_rows)) or ~100 MB for
133
- # typical time series inputs. This function uses `del` to
134
- # allow python to recapture intermediate variables and
135
- # reduce peak memory usage .
128
+ # typical time series inputs. This function makes heavy
129
+ # use of numpy's out parameter to avoid allocating new
130
+ # memory. Unfortunately that comes at the cost of readability .
136
131
137
132
# handle floats:
138
133
x = np .atleast_1d (x )[:, np .newaxis , np .newaxis ]
@@ -143,29 +138,27 @@ def _vf_ground_sky_2d(x, rotation, gcr, pitch, height, max_rows=10):
143
138
dy = width * sind (rotation )
144
139
dx = width * cosd (rotation )
145
140
141
+ phi = np .empty ((2 , x .shape [0 ], rotation .shape [1 ], len (all_k )))
142
+
146
143
# angles from x to right edge of each row
147
144
a1 = height + dy
148
- b1 = distance_to_row_centers + dx
149
- phi_1 = np .arctan2 (a1 , b1 ) # dimensions: (x, rotation, row)
150
- del a1 , b1 # reduce max memory usage
145
+ phi [0 ] = distance_to_row_centers + dx
146
+ np .arctan2 (a1 , phi [0 ], out = phi [0 ])
151
147
152
148
# angles from x to left edge of each row
153
149
a2 = height - dy
154
- b2 = distance_to_row_centers - dx
155
- phi_2 = np .arctan2 (a2 , b2 ) # dimensions: (x, rotation, row)
156
- del a2 , b2 # reduce max memory usage
157
-
158
- phi = np .stack ([phi_1 , phi_2 ]) # dimensions: (row edge, x, rotation, row)
159
- swap = phi_1 > phi_2
160
- del phi_1 , phi_2 # reduce max memory usage
150
+ phi [1 ] = distance_to_row_centers - dx
151
+ np .arctan2 (a2 , phi [1 ], out = phi [1 ])
161
152
162
- # swap where phi_1 > phi_2 so that phi[0,:,:,:] is the lesser angle
163
- phi = np .where (swap , phi [::- 1 ], phi )
164
- del swap # reduce max memory usage
153
+ # swap angles so that phi[0,:,:,:] is the lesser angle
154
+ phi .sort (axis = 0 )
165
155
166
156
# right edge of next row - left edge of previous row
167
- wedge_vfs = 0.5 * (np .cos (phi [1 , :, :, 1 :]) - np .cos (phi [0 , :, :, :- 1 ]))
168
- vf = np .sum (np .clip (wedge_vfs , a_min = 0. , a_max = None ), axis = - 1 )
169
- del wedge_vfs # reduce max memory usage
170
-
171
- return vf , np .degrees (phi )
157
+ next_edge = phi [1 , :, :, 1 :]
158
+ np .cos (next_edge , out = next_edge )
159
+ prev_edge = phi [0 , :, :, :- 1 ]
160
+ np .cos (prev_edge , out = prev_edge )
161
+ np .subtract (next_edge , prev_edge , out = next_edge )
162
+ np .clip (next_edge , a_min = 0. , a_max = None , out = next_edge )
163
+ vf = np .sum (next_edge , axis = - 1 ) / 2
164
+ return vf
0 commit comments