def __init__(self, phase_obj_3d, wavelength, slice_binning_factor=1, **kwargs): """ Initialization of the class phase_obj_3d: object of the class PhaseObject3D wavelength: wavelength of the light slice_binning_factor: the object is compress in z-direction by this factor """ self.slice_binning_factor = slice_binning_factor self._shape_full = phase_obj_3d.shape self.shape = phase_obj_3d.shape[0:2] + (int( np.ceil(phase_obj_3d.shape[2] / self.slice_binning_factor)), ) self.RI = phase_obj_3d.RI self.wavelength = wavelength self.pixel_size = phase_obj_3d.pixel_size self.pixel_size_z = phase_obj_3d.pixel_size_z * self.slice_binning_factor self.back_scatter = False #Broadcasts b to a, size(a) > size(b) self.assign_broadcast = lambda a, b: a - a + b fxlin, fylin = self._genFrequencyGrid() self.fzlin = ((self.RI / self.wavelength)**2 - fxlin * af.conjg(fxlin) - fylin * af.conjg(fylin))**0.5 self.prop_kernel_phase = 1.0j * 2.0 * np.pi * self.fzlin
def adjoint(self, residual, cache): V_obj_af, field_layer_in_or_grad,\ flag_gpu_inout = cache #back-propagte to volume center field_bp = residual if self.focus_at_center: #propagate to the last layer field_bp = self._propagationInplace(field_bp, self.distance_end_to_center) for layer in range(self.shape[2] - 1, -1, -1): field_bp_1 = af.ifft2( af.fft2(field_bp) * af.conjg(self.green_kernel_2d)) * self.pixel_size_z if layer > 0: field_bp = self._propagationInplace( field_bp, self.slice_separation[layer], adjoint=True) field_bp[:, :] += field_bp_1 * af.conjg(V_obj_af[:, :, layer]) field_layer_in_or_grad[:, :, layer] = field_bp_1 * af.conjg( field_layer_in_or_grad[:, :, layer]) #Unbinning grad = self._meanObject(field_layer_in_or_grad, adjoint=True) if flag_gpu_inout: return {'gradient': grad} else: return {'gradient': np.array(grad)}
def __init__(self, shape, pixel_size, wavelength, na, RI_measure=1.0, **kwargs): """ Initialization of the class RI_measure: refractive index on the detection side (example: oil immersion objectives) """ super().__init__(shape, pixel_size, na, **kwargs) fxlin = genGrid(self.shape[1], 1.0 / self.pixel_size / self.shape[1], flag_shift=True) fylin = genGrid(self.shape[0], 1.0 / self.pixel_size / self.shape[0], flag_shift=True) fxlin = af.tile(fxlin.T, self.shape[0], 1) fylin = af.tile(fylin, 1, self.shape[1]) self.pupil_support = genPupil(self.shape, self.pixel_size, self.na, wavelength) self.prop_kernel_phase = 1.0j * 2.0 * np.pi * self.pupil_support * ( (RI_measure / wavelength)**2 - fxlin * af.conjg(fxlin) - fylin * af.conjg(fylin))**0.5
def _split_fourier_cuda(self, signal: Signal, step): ''' This function is called by split_fourier,and should not be used outside :param signal: signal to traverse the span :param step: the step of split fourier :return: None ''' af.set_backend('cuda') freq = fftfreq(len(signal.data_sample[0, :]), (signal.sps * signal.symbol_rate_in_hz)**(-1)) freq = af.Array(freq.ctypes.data, freq.shape, freq.dtype.char) signal_x = np.asarray(signal.data_sample[0, :]) signal_y = np.asarray(signal.data_sample[1, :]) signal_x = af.Array(signal_x.ctypes.data, signal_x.shape, dtype=signal_x.dtype.char) signal_y = af.Array(signal_y.ctypes.data, signal_x.shape, dtype=signal_y.dtype.char) Disper = (1j / 2) * self.beta2 * (2 * np.pi * freq)**2 * step + ( 1j / 6) * self.beta3 * ( (2 * np.pi * freq)**3 * step) - self.alphalin / 2 * step dz_Eff = (1 - np.exp(-self.alphalin * step)) / self.alphalin step_number = np.ceil(self.length / step) for number in range(int(step_number)): print(number) if number == step_number - 1: # dz = step dz = self.length - (step_number - 1) * step dz_Eff = (1 - np.exp(-self.alphalin * dz)) / self.alphalin Disper = (1j / 2) * self.beta2 * (2 * np.pi * freq)**2 * dz + ( 1j / 6) * self.beta3 * ( (2 * np.pi * freq)**3 * dz) - self.alphalin / 2 * step signal_x, signal_y = self.linear(signal_x, signal_y, Disper) energy = signal_x * af.conjg(signal_x) + signal_y * af.conjg( signal_y) signal_x, signal_y = self.nonlinear(energy, signal_x, signal_y, dz_Eff) signal_x, signal_y = self.linear(signal_x, signal_y, Disper) signal_x_array = np.array(signal_x.to_list()) signal_y_array = np.array(signal_y.to_list()) signal_x_array = signal_x_array[:, 0] + 1j * signal_x_array[:, 1] signal_y_array = signal_y_array[:, 0] + 1j * signal_y_array[:, 1] signal.data_sample[0, :] = signal_x_array signal.data_sample[1, :] = signal_y_array
def func(x0): fields = self._scattering_obj.forward(x0, fx_illu, fy_illu) field_scattered = self._defocus_obj.forward(field_scattered, self.prop_distances) field_measure = self._crop_obj.forward(field_scattered) residual = af.abs(field_measure) - amplitude function_value = af.sum(residual*af.conjg(residual)).real return function_value
def adjoint(self, residual, cache): phasecontrast_obj_af, field_layer_conj_or_grad, flag_gpu_inout = cache trans_obj_af_conj = af.conjg(phasecontrast_obj_af) #back-propagte to volume center field_bp = residual #propagate to the last layer if self.focus_at_center: field_bp = self._propagationInplace(field_bp, self.distance_end_to_center) #multi-slice transmittance backward for layer in range(self.shape[2] - 1, -1, -1): field_layer_conj_or_grad[:, :, layer] = field_bp * field_layer_conj_or_grad[:, :, layer] * ( -1.0j ) * self.sigma * trans_obj_af_conj[:, :, layer] if layer > 0: field_bp[:, :] *= trans_obj_af_conj[:, :, layer] field_bp = self._propagationInplace( field_bp, self.slice_separation[layer - 1], adjoint=True) #Unbinning grad = self._binObject(field_layer_conj_or_grad, adjoint=True) phasecontrast_obj_af = None if flag_gpu_inout: return {'gradient': grad} else: return {'gradient': np.array(grad)}
def conj(self): if not numpy.issubdtype(self.dtype, numpy.complex): return afnumpy.copy(self) if(self.d_array is not None): s = arrayfire.conjg(self.d_array) return ndarray(self.shape, dtype=pu.typemap(s.dtype()), af_array=s) else: return self.h_array.conj()
def adjoint(self, field): """Adjoint operator for pupil (and estimate pupil if selected)""" field_adj_f = af.fft2(field) field_pupil_adj = af.ifft2(af.conjg(self.getPupil()) * field_adj_f) #Pupil recovery if self.flag_update: self._update(field_adj_f) return field_pupil_adj
def forward(self, field, **kwargs): """Apply pupil""" self.field_f = af.fft2(field) if self.flag_update: if self.update_method == "GaussNewton": self.approx_hessian[:, :] += self.field_f * af.conjg( self.field_f) field = af.ifft2(self.getPupil() * self.field_f) return field
def __init__(self, phase_obj_3d, wavelength, **kwargs): super().__init__(phase_obj_3d, wavelength, **kwargs) self.distance_end_to_center = np.sum( self.slice_separation) / 2. + phase_obj_3d.slice_separation[-1] self.distance_beginning_to_center = np.sum(self.slice_separation) / 2. self.slice_separation = np.append(phase_obj_3d.slice_separation, [phase_obj_3d.slice_separation[-1]]) self.slice_separation = np.asarray([sum(self.slice_separation[x:x+self.slice_binning_factor]) \ for x in range(0,len(self.slice_separation),self.slice_binning_factor)]) if self.slice_separation.shape[0] != self.shape[2]: print( "Number of slices does not match with number of separations!") # generate green's function convolution kernel fxlin, fylin = self._genFrequencyGrid() kernel_mask = (self.RI / self.wavelength)**2 > 1.01 * ( fxlin * af.conjg(fxlin) + fylin * af.conjg(fylin)) self.green_kernel_2d = -0.25j * af.exp( 2.0j * np.pi * self.fzlin * self.pixel_size_z) / np.pi / self.fzlin self.green_kernel_2d *= kernel_mask self.green_kernel_2d[af.isnan(self.green_kernel_2d) == 1] = 0.0
def forward(self, contrast_obj, fx_illu, fy_illu): #compute illumination with contexttimer.Timer() as timer: field, fx_illu, fy_illu, fz_illu = self._genIllumination( fx_illu, fy_illu) field[:, :] *= np.exp(1.0j * 2.0 * np.pi * fz_illu * self.initial_z_position) field_layer_conj = af.constant(0.0, self.shape[0], self.shape[1], self.shape[2], dtype=af_complex_datatype) if (type(contrast_obj).__module__ == np.__name__): phasecontrast_obj_af = af.to_array(contrast_obj) flag_gpu_inout = False else: phasecontrast_obj_af = contrast_obj flag_gpu_inout = True #Binning obj_af = self._binObject(phasecontrast_obj_af) #Potentials to Transmittance obj_af = af.exp(1.0j * self.sigma * obj_af) for layer in range(self.shape[2]): field_layer_conj[:, :, layer] = af.conjg(field) field[:, :] *= obj_af[:, :, layer] if layer < self.shape[2] - 1: field = self._propagationInplace( field, self.slice_separation[layer]) #propagate to volume center cache = (obj_af, field_layer_conj, flag_gpu_inout) if self.focus_at_center: #propagate to volume center field = self._propagationInplace(field, self.distance_end_to_center, adjoint=True) return {'forward_scattered_field': field, 'cache': cache}
def _update(self, field_adj_f): """function to recover pupil""" self.pupil_gradient_phase[:, :] += af.conjg(self.field_f) * field_adj_f self.measure_count += 1 if self.measure_count == self.measurement_num: if self.update_method == "gradient": self.pupil[:, :] -= self.pupil_step_size * self.pupil_gradient_phase * self.pupil_support elif self.update_method == "GaussNewton": self.pupil[:, :] -= self.pupil_step_size * af.abs( self.field_f ) * self.pupil_gradient_phase * self.pupil_support / ( (self.approx_hessian + 1e-3) * af.max(af.abs(self.field_f[:]))) self.approx_hessian[:, :] = 0.0 else: print("there is no update_method \"%s\"!" % (self.update_method)) raise self.pupil_gradient_phase[:, :] = 0.0 self.measure_count = 0
def forward(self, trans_obj, fx_illu, fy_illu): if self.slice_binning_factor > 1: print( "Slicing is not implemented for MultiTransmittance algorithm!") raise #compute illumination field, fx_illu, fy_illu, fz_illu = self._genIllumination( fx_illu, fy_illu) field[:, :] *= np.exp(1.0j * 2.0 * np.pi * fz_illu * self.initial_z_position) #multi-slice transmittance forward propagation field_layer_conj = af.constant(0.0, trans_obj.shape[0], trans_obj.shape[1], trans_obj.shape[2], dtype=af_complex_datatype) if (type(trans_obj).__module__ == np.__name__): trans_obj_af = af.to_array(trans_obj) flag_gpu_inout = False else: trans_obj_af = trans_obj flag_gpu_inout = True for layer in range(self.shape[2]): field_layer_conj[:, :, layer] = af.conjg(field) field[:, :] *= trans_obj_af[:, :, layer] if layer < self.shape[2] - 1: field = self._propagationInplace(field, self.slice_separation[layer]) #store intermediate variables for adjoint operation cache = (trans_obj_af, field_layer_conj, flag_gpu_inout) if self.focus_at_center: #propagate to volume center field = self._propagationInplace(field, self.distance_end_to_center, adjoint=True) return {'forward_scattered_field': field, 'cache': cache}
def propKernel(shape, pixel_size, wavelength, prop_distance, NA=None, RI=1.0, band_limited=True): assert len(shape) == 2, "pupil should be two dimensional!" fxlin = genGrid(shape[1], 1 / pixel_size / shape[1], flag_shift=True) fylin = genGrid(shape[0], 1 / pixel_size / shape[0], flag_shift=True) fxlin = af.tile(fxlin.T, shape[0], 1) fylin = af.tile(fylin, 1, shape[1]) if band_limited: assert NA is not None, "need to provide numerical aperture of the system!" Pcrop = genPupil(shape, pixel_size, NA, wavelength) else: Pcrop = 1.0 prop_kernel = Pcrop * af.exp(1.0j * 2.0 * np.pi * abs(prop_distance) * Pcrop *\ ((RI/wavelength)**2 - fxlin**2 - fylin**2)**0.5) prop_kernel = af.conjg(prop_kernel) if prop_distance < 0 else prop_kernel return prop_kernel
def adjoint(self, residual, cache): trans_obj_af, field_layer_conj_or_grad, flag_gpu_inout = cache #back-propagte to volume center field_bp = residual if self.focus_at_center: #propagate to the last layer field_bp = self._propagationInplace(field_bp, self.distance_end_to_center) #multi-slice transmittance backward for layer in range(self.shape[2] - 1, -1, -1): field_layer_conj_or_grad[:, :, layer] = field_bp * field_layer_conj_or_grad[:, :, layer] if layer > 0: field_bp[:, :] *= af.conjg(trans_obj_af[:, :, layer]) field_bp = self._propagationInplace( field_bp, self.slice_separation[layer - 1], adjoint=True) if flag_gpu_inout: return {'gradient': field_layer_conj_or_grad} else: return {'gradient': np.array(field_layer_conj_or_grad)}
def _propagationInplace(self, field, propagation_distance, adjoint=False, in_real=True): """ propagation operator that uses angular spectrum to propagate the wave field: input field propagation_distance: distance to propagate the wave adjoint: boolean variable to perform adjoint operation (i.e. opposite direction) """ if in_real: af.fft2_inplace(field) if adjoint: field[:, :] *= af.conjg( af.exp(self.prop_kernel_phase * propagation_distance)) else: field[:, :] *= af.exp(self.prop_kernel_phase * propagation_distance) if in_real: af.ifft2_inplace(field) return field
def simple_arith(verbose=False): display_func = _util.display_func(verbose) print_func = _util.print_func(verbose) a = af.randu(3, 3) b = af.constant(4, 3, 3) display_func(a) display_func(b) c = a + b d = a d += b display_func(c) display_func(d) display_func(a + 2) display_func(3 + a) c = a - b d = a d -= b display_func(c) display_func(d) display_func(a - 2) display_func(3 - a) c = a * b d = a d *= b display_func(c * 2) display_func(3 * d) display_func(a * 2) display_func(3 * a) c = a / b d = a d /= b display_func(c / 2.0) display_func(3.0 / d) display_func(a / 2) display_func(3 / a) c = a % b d = a d %= b display_func(c % 2.0) display_func(3.0 % d) display_func(a % 2) display_func(3 % a) c = a**b d = a d **= b display_func(c**2.0) display_func(3.0**d) display_func(a**2) display_func(3**a) display_func(a < b) display_func(a < 0.5) display_func(0.5 < a) display_func(a <= b) display_func(a <= 0.5) display_func(0.5 <= a) display_func(a > b) display_func(a > 0.5) display_func(0.5 > a) display_func(a >= b) display_func(a >= 0.5) display_func(0.5 >= a) display_func(a != b) display_func(a != 0.5) display_func(0.5 != a) display_func(a == b) display_func(a == 0.5) display_func(0.5 == a) a = af.randu(3, 3, dtype=af.Dtype.u32) b = af.constant(4, 3, 3, dtype=af.Dtype.u32) display_func(a & b) display_func(a & 2) c = a c &= 2 display_func(c) display_func(a | b) display_func(a | 2) c = a c |= 2 display_func(c) display_func(a >> b) display_func(a >> 2) c = a c >>= 2 display_func(c) display_func(a << b) display_func(a << 2) c = a c <<= 2 display_func(c) display_func(-a) display_func(+a) display_func(~a) display_func(a) display_func(af.cast(a, af.Dtype.c32)) display_func(af.maxof(a, b)) display_func(af.minof(a, b)) display_func(af.rem(a, b)) a = af.randu(3, 3) - 0.5 b = af.randu(3, 3) - 0.5 display_func(af.abs(a)) display_func(af.arg(a)) display_func(af.sign(a)) display_func(af.round(a)) display_func(af.trunc(a)) display_func(af.floor(a)) display_func(af.ceil(a)) display_func(af.hypot(a, b)) display_func(af.sin(a)) display_func(af.cos(a)) display_func(af.tan(a)) display_func(af.asin(a)) display_func(af.acos(a)) display_func(af.atan(a)) display_func(af.atan2(a, b)) c = af.cplx(a) d = af.cplx(a, b) display_func(c) display_func(d) display_func(af.real(d)) display_func(af.imag(d)) display_func(af.conjg(d)) display_func(af.sinh(a)) display_func(af.cosh(a)) display_func(af.tanh(a)) display_func(af.asinh(a)) display_func(af.acosh(a)) display_func(af.atanh(a)) a = af.abs(a) b = af.abs(b) display_func(af.root(a, b)) display_func(af.pow(a, b)) display_func(af.pow2(a)) display_func(af.sigmoid(a)) display_func(af.exp(a)) display_func(af.expm1(a)) display_func(af.erf(a)) display_func(af.erfc(a)) display_func(af.log(a)) display_func(af.log1p(a)) display_func(af.log10(a)) display_func(af.log2(a)) display_func(af.sqrt(a)) display_func(af.cbrt(a)) a = af.round(5 * af.randu(3, 3) - 1) b = af.round(5 * af.randu(3, 3) - 1) display_func(af.factorial(a)) display_func(af.tgamma(a)) display_func(af.lgamma(a)) display_func(af.iszero(a)) display_func(af.isinf(a / b)) display_func(af.isnan(a / a)) a = af.randu(5, 1) b = af.randu(1, 5) c = af.broadcast(lambda x, y: x + y, a, b) display_func(a) display_func(b) display_func(c) @af.broadcast def test_add(aa, bb): return aa + bb display_func(test_add(a, b))
def conj(self): if not numpy.issubdtype(self.dtype, numpy.complex): return afnumpy.copy(self) s = arrayfire.conjg(self.d_array) return ndarray(self.shape, dtype=pu.typemap(s.dtype()), af_array=s)
def cong(arr): return af.conjg(arr)
af.display(af.hypot(a, b)) af.display(af.sin(a)) af.display(af.cos(a)) af.display(af.tan(a)) af.display(af.asin(a)) af.display(af.acos(a)) af.display(af.atan(a)) af.display(af.atan2(a, b)) c = af.cplx(a) d = af.cplx(a, b) af.display(c) af.display(d) af.display(af.real(d)) af.display(af.imag(d)) af.display(af.conjg(d)) af.display(af.sinh(a)) af.display(af.cosh(a)) af.display(af.tanh(a)) af.display(af.asinh(a)) af.display(af.acosh(a)) af.display(af.atanh(a)) a = af.abs(a) b = af.abs(b) af.display(af.root(a, b)) af.display(af.pow(a, b)) af.display(af.pow2(a)) af.display(af.exp(a))
def cart2Pol(x, y): rho = (x * af.conjg(x) + y * af.conjg(y))**0.5 theta = af.atan2(af.real(y), af.real(x)).as_type(af_complex_datatype) return rho, theta
def vdot(a, b): s = arrayfire.dot(arrayfire.conjg(a.flat.d_array), b.flat.d_array) return afnumpy.ndarray((), dtype=a.dtype, af_array=s)[()]
def simple_arith(verbose = False): display_func = _util.display_func(verbose) print_func = _util.print_func(verbose) a = af.randu(3,3,dtype=af.Dtype.u32) b = af.constant(4, 3, 3, dtype=af.Dtype.u32) display_func(a) display_func(b) c = a + b d = a d += b display_func(c) display_func(d) display_func(a + 2) display_func(3 + a) c = a - b d = a d -= b display_func(c) display_func(d) display_func(a - 2) display_func(3 - a) c = a * b d = a d *= b display_func(c * 2) display_func(3 * d) display_func(a * 2) display_func(3 * a) c = a / b d = a d /= b display_func(c / 2.0) display_func(3.0 / d) display_func(a / 2) display_func(3 / a) c = a % b d = a d %= b display_func(c % 2.0) display_func(3.0 % d) display_func(a % 2) display_func(3 % a) c = a ** b d = a d **= b display_func(c ** 2.0) display_func(3.0 ** d) display_func(a ** 2) display_func(3 ** a) display_func(a < b) display_func(a < 0.5) display_func(0.5 < a) display_func(a <= b) display_func(a <= 0.5) display_func(0.5 <= a) display_func(a > b) display_func(a > 0.5) display_func(0.5 > a) display_func(a >= b) display_func(a >= 0.5) display_func(0.5 >= a) display_func(a != b) display_func(a != 0.5) display_func(0.5 != a) display_func(a == b) display_func(a == 0.5) display_func(0.5 == a) display_func(a & b) display_func(a & 2) c = a c &= 2 display_func(c) display_func(a | b) display_func(a | 2) c = a c |= 2 display_func(c) display_func(a >> b) display_func(a >> 2) c = a c >>= 2 display_func(c) display_func(a << b) display_func(a << 2) c = a c <<= 2 display_func(c) display_func(-a) display_func(+a) display_func(~a) display_func(a) display_func(af.cast(a, af.Dtype.c32)) display_func(af.maxof(a,b)) display_func(af.minof(a,b)) display_func(af.rem(a,b)) a = af.randu(3,3) - 0.5 b = af.randu(3,3) - 0.5 display_func(af.abs(a)) display_func(af.arg(a)) display_func(af.sign(a)) display_func(af.round(a)) display_func(af.trunc(a)) display_func(af.floor(a)) display_func(af.ceil(a)) display_func(af.hypot(a, b)) display_func(af.sin(a)) display_func(af.cos(a)) display_func(af.tan(a)) display_func(af.asin(a)) display_func(af.acos(a)) display_func(af.atan(a)) display_func(af.atan2(a, b)) c = af.cplx(a) d = af.cplx(a,b) display_func(c) display_func(d) display_func(af.real(d)) display_func(af.imag(d)) display_func(af.conjg(d)) display_func(af.sinh(a)) display_func(af.cosh(a)) display_func(af.tanh(a)) display_func(af.asinh(a)) display_func(af.acosh(a)) display_func(af.atanh(a)) a = af.abs(a) b = af.abs(b) display_func(af.root(a, b)) display_func(af.pow(a, b)) display_func(af.pow2(a)) display_func(af.exp(a)) display_func(af.expm1(a)) display_func(af.erf(a)) display_func(af.erfc(a)) display_func(af.log(a)) display_func(af.log1p(a)) display_func(af.log10(a)) display_func(af.log2(a)) display_func(af.sqrt(a)) display_func(af.cbrt(a)) a = af.round(5 * af.randu(3,3) - 1) b = af.round(5 * af.randu(3,3) - 1) display_func(af.factorial(a)) display_func(af.tgamma(a)) display_func(af.lgamma(a)) display_func(af.iszero(a)) display_func(af.isinf(a/b)) display_func(af.isnan(a/a)) a = af.randu(5, 1) b = af.randu(1, 5) c = af.broadcast(lambda x,y: x+y, a, b) display_func(a) display_func(b) display_func(c) @af.broadcast def test_add(aa, bb): return aa + bb display_func(test_add(a, b))
def _solveFirstOrderGradient(self, measurements, verbose, callback=None): """ MAIN part of the solver, runs the FISTA algorithm configs: configs object from class AlgorithmConfigs measurements: all measurements self.configs.recon_from_field == True: field self.configs.recon_from_field == False: amplitude measurement verbose: boolean variable to print verbosely """ flag_FISTA = False if self.configs.method == "FISTA": flag_FISTA = True # update multiple angles at a time batch_update = False if self.configs.fista_global_update or self.configs.batch_size != 1: gradient_batch = af.constant(0.0, self.phase_obj_3d.shape[0],\ self.phase_obj_3d.shape[1],\ self.phase_obj_3d.shape[2], dtype = af_complex_datatype) batch_update = True if self.configs.fista_global_update: self.configs.batch_size = 0 #TODO: what if num_batch is not an integer if self.configs.batch_size == 0: num_batch = 1 else: num_batch = self.number_illum // self.configs.batch_size stepsize = self.configs.stepsize max_iter = self.configs.max_iter reg_term = self.configs.reg_term self.configs.error = [] obj_gpu = af.constant(0.0, self.phase_obj_3d.shape[0],\ self.phase_obj_3d.shape[1],\ self.phase_obj_3d.shape[2], dtype = af_complex_datatype) #Initialization for FISTA update if flag_FISTA: restart = self.configs.restart y_k = self._x.copy() t_k = 1.0 #Set Callback flag if callback is None: run_callback = False else: run_callback = True #Start of iterative algorithm with contexttimer.Timer() as timer: if verbose: print("---- Start of the %5s algorithm ----" %(self.scat_model)) for iteration in range(max_iter): illu_counter = 0 cost = 0.0 obj_gpu[:] = af.to_array(self._x) if self.configs.random_order: illu_order = np.random.permutation(range(self.number_illum)) else: illu_order = range(self.number_illum) for batch_idx in range(num_batch): if batch_update: gradient_batch[:,:,:] = 0.0 if self.configs.batch_size == 0: illu_indices = illu_order else: illu_indices = illu_order[batch_idx * self.configs.batch_size : (batch_idx+1) * self.configs.batch_size] for illu_idx in illu_indices: #forward scattering fx_illu = self.fx_illu_list[illu_idx] fy_illu = self.fy_illu_list[illu_idx] fields = self._forwardMeasure(fx_illu, fy_illu, obj = obj_gpu) #calculate error measurement = af.to_array(measurements[:,:,:,illu_idx].astype(np_complex_datatype)) if self.configs.recon_from_field: residual = fields["forward_scattered_field"] - measurement else: if self.configs.cost_criterion == "intensity": residual = af.abs(fields["forward_scattered_field"])**2 - measurement**2 elif self.configs.cost_criterion == "amplitude": residual = af.abs(fields["forward_scattered_field"]) - measurement cost += af.sum(residual*af.conjg(residual)).real #calculate gradient if batch_update: gradient_batch[:, :, :] += self._computeGradient(fields, measurement)[0] else: gradient = self._computeGradient(fields, measurement) obj_gpu[:, :, :] -= stepsize * gradient if verbose: if self.number_illum > 1: print("gradient update of illumination {:03d}/{:03d}.".format(illu_counter, self.number_illum), end="\r") illu_counter += 1 fields = None residual = None gradient = None measurement = None pupil = None af.device_gc() if batch_update: obj_gpu[:, :, :] -= stepsize * gradient_batch if np.isnan(obj_gpu).sum() > 0: stepsize *= 0.1 self.configs.time_elapsed = timer.elapsed print("WARNING: Gradient update diverges! Resetting stepsize to %3.2f" %(stepsize)) t_k = 1.0 continue # L2 regularizer obj_gpu[:, :, :] -= stepsize * reg_term * obj_gpu #record total error self.configs.error.append(cost + reg_term * af.sum(obj_gpu*af.conjg(obj_gpu)).real) #Prox operators af.device_gc() obj_gpu = self._regularizer_obj.applyRegularizer(obj_gpu) if flag_FISTA: #check convergence if iteration > 0: if self.configs.error[-1] > self.configs.error[-2]: if restart: t_k = 1.0 self._x[:, :, :] = y_k # stepsize *= 0.8 print("WARNING: FISTA Restart! Error: %5.5f" %(np.log10(self.configs.error[-1]))) if run_callback: callback(self._x, self.configs) continue else: print("WARNING: Error increased! Error: %5.5f" %(np.log10(self.configs.error[-1]))) #FISTA auxiliary variable y_k1 = np.array(obj_gpu) if len(y_k1.shape) < 3: y_k1 = y_k1[:,:,np.newaxis] #FISTA update t_k1 = 0.5*(1.0 + (1.0 + 4.0*t_k**2)**0.5) beta = (t_k - 1.0) / t_k1 self._x[:, :, :] = y_k1 + beta * (y_k1 - y_k) t_k = t_k1 y_k = y_k1.copy() else: #check convergence temp = np.array(obj_gpu) if len(temp.shape) < 3: temp = temp[:,:,np.newaxis] self._x[:, :, :] = temp if iteration > 0: if self.configs.error[-1] > self.configs.error[-2]: print("WARNING: Error increased! Error: %5.5f" %(np.log10(self.configs.error[-1]))) stepsize *= 0.8 if verbose: print("iteration: %d/%d, error: %5.5f, elapsed time: %5.2f seconds" %(iteration+1, max_iter, np.log10(self.configs.error[-1]), timer.elapsed)) if run_callback: callback(self._x, self.configs) self.configs.time_elapsed = timer.elapsed return self._x
af.display(af.hypot(a, b)) af.display(af.sin(a)) af.display(af.cos(a)) af.display(af.tan(a)) af.display(af.asin(a)) af.display(af.acos(a)) af.display(af.atan(a)) af.display(af.atan2(a, b)) c = af.cplx(a) d = af.cplx(a,b) af.display(c) af.display(d) af.display(af.real(d)) af.display(af.imag(d)) af.display(af.conjg(d)) af.display(af.sinh(a)) af.display(af.cosh(a)) af.display(af.tanh(a)) af.display(af.asinh(a)) af.display(af.acosh(a)) af.display(af.atanh(a)) a = af.abs(a) b = af.abs(b) af.display(af.root(a, b)) af.display(af.pow(a, b)) af.display(af.pow2(a)) af.display(af.exp(a))