@@ -122,17 +122,12 @@ def _vf_ground_sky_2d(x, rotation, gcr, pitch, height, max_rows=10):
122122 vf : array
123123 Fraction of sky dome visible from each point on the ground.
124124 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]
130125 """
131126 # This function creates large float64 arrays of size
132127 # (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 .
136131
137132 # handle floats:
138133 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):
143138 dy = width * sind (rotation )
144139 dx = width * cosd (rotation )
145140
141+ phi = np .empty ((2 , x .shape [0 ], rotation .shape [1 ], len (all_k )))
142+
146143 # angles from x to right edge of each row
147144 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 ])
151147
152148 # angles from x to left edge of each row
153149 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 ])
161152
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 )
165155
166156 # 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