Commit 41879da1 by Martin Reinecke

### DiagonalOperator takes and returns diagonal without volume factors

parent 88872f64
Pipeline #19209 failed with stage
 ... ... @@ -72,7 +72,7 @@ if __name__ == "__main__": R = AdjointFFTResponse(fft, Instrument) noise = 1. N = ift.DiagonalOperator(ift.Field(s_space,noise).weight(1)) N = ift.DiagonalOperator(ift.Field(s_space,noise)) n = ift.Field.from_random(domain=s_space, random_type='normal', std=np.sqrt(noise), ... ...
 ... ... @@ -38,7 +38,7 @@ if __name__ == "__main__": R_harmonic = ift.ComposedOperator([fft, R]) # Setting up the noise covariance and drawing a random noise realization ndiag = ift.Field(data_domain, mock_signal.var()/signal_to_noise).weight(1) ndiag = ift.Field(data_domain, mock_signal.var()/signal_to_noise) N = ift.DiagonalOperator(ndiag) noise = ift.Field.from_random(domain=data_domain, random_type='normal', std=mock_signal.std()/np.sqrt(signal_to_noise), mean=0) ... ...
 ... ... @@ -62,7 +62,7 @@ if __name__ == "__main__": diagonal = mock_power.power_synthesize_special(spaces=(0, 1))**2 diagonal = diagonal.real S = ift.DiagonalOperator(diagonal) S = ift.DiagonalOperator(diagonal.weight(-1)) np.random.seed(10) ... ... @@ -84,7 +84,7 @@ if __name__ == "__main__": R_harmonic = ift.ComposedOperator([fft, R]) # Setting up the noise covariance and drawing a random noise realization ndiag = ift.Field(data_domain, mock_signal.var()/signal_to_noise).weight(1) ndiag = ift.Field(data_domain, mock_signal.var()/signal_to_noise) N = ift.DiagonalOperator(ndiag) noise = ift.Field.from_random(domain=data_domain, random_type='normal', std=mock_signal.std()/np.sqrt(signal_to_noise), ... ... @@ -93,7 +93,7 @@ if __name__ == "__main__": # Wiener filter j = R_harmonic.adjoint_times(N.inverse_times(data)) ctrl = ift.GradientNormController(verbose=True, iteration_limit=100) ctrl = ift.GradientNormController(verbose=True, tol_abs_gradnorm=0.1) inverter = ift.ConjugateGradient(controller=ctrl) wiener_curvature = ift.library.WienerFilterCurvature(S=S, N=N, R=R_harmonic, inverter=inverter) ... ...
 ... ... @@ -37,7 +37,7 @@ if __name__ == "__main__": R_harmonic = ift.ComposedOperator([fft, R]) # Setting up the noise covariance and drawing a random noise realization ndiag = ift.Field(data_domain, mock_signal.var()/signal_to_noise).weight(1) ndiag = ift.Field(data_domain, mock_signal.var()/signal_to_noise) N = ift.DiagonalOperator(ndiag) noise = ift.Field.from_random(domain=data_domain, random_type='normal', std=mock_signal.std()/np.sqrt(signal_to_noise), mean=0) ... ...
 ... ... @@ -47,7 +47,7 @@ if __name__ == "__main__": data_domain = R.target[0] R_harmonic = ift.ComposedOperator([fft, R]) N = ift.DiagonalOperator(ift.Field(data_domain,mock_signal.var()/signal_to_noise).weight(1)) N = ift.DiagonalOperator(ift.Field(data_domain,mock_signal.var()/signal_to_noise)) noise = ift.Field.from_random(domain=data_domain, random_type='normal', std=mock_signal.std()/np.sqrt(signal_to_noise), ... ...
 ... ... @@ -62,7 +62,7 @@ if __name__ == "__main__": # Adding a harmonic transformation to the instrument R = AdjointFFTResponse(fft, Instrument) signal_to_noise = 1. ndiag = ift.Field(s_space, ss.var()/signal_to_noise).weight(1) ndiag = ift.Field(s_space, ss.var()/signal_to_noise) N = ift.DiagonalOperator(ndiag) n = ift.Field.from_random(domain=s_space, random_type='normal', ... ...
 ... ... @@ -420,7 +420,7 @@ class Field(object): res *= tmp return res def weight(self, power=1, inplace=False, spaces=None): def weight(self, power=1, spaces=None, out=None): """ Weights the pixels of `self` with their invidual pixel-volume. Parameters ... ... @@ -428,20 +428,25 @@ class Field(object): power : number The pixels get weighted with the volume-factor**power. inplace : boolean If True, `self` will be weighted and returned. Otherwise, a copy is made. spaces : tuple of ints Determines on which subspace the operation takes place. out : Field or None if not None, the result is returned in a new Field otherwise the contents of "out" are overwritten with the result. "out" may be identical to "self"! Returns ------- out : Field The weighted field. """ new_field = self if inplace else self.copy() if out is None: out = self.copy() else: if out is not self: out.copy_content_from(self) if spaces is None: spaces = range(len(self.domain)) ... ... @@ -458,12 +463,12 @@ class Field(object): new_shape[self.domain.axes[ind][0]: self.domain.axes[ind][-1]+1] = wgt.shape wgt = wgt.reshape(new_shape) new_field *= wgt**power out *= wgt**power fct = fct**power if fct != 1.: new_field *= fct out *= fct return new_field return out def vdot(self, x=None, spaces=None): """ Computes the volume-factor-aware dot product of 'self' with x. ... ... @@ -474,8 +479,8 @@ class Field(object): The domain of x must contain `self.domain` spaces : tuple of ints If the domain of `self` and `x` are not the same, `spaces` specfies the mapping. If the domain of `self` and `x` are not the same, `spaces` defines which domains of `x` are mapped to those of `self`. Returns ------- ... ... @@ -487,9 +492,9 @@ class Field(object): "the NIFTy field class") # Compute the dot respecting the fact of discrete/continuous spaces fct = 1. tmp = self.scalar_weight(spaces) if tmp is None: fct = 1. y = self.weight(power=1) else: y = self ... ... @@ -498,13 +503,14 @@ class Field(object): if spaces is None: return fct*dobj.vdot(y.val.ravel(), x.val.ravel()) else: # create a diagonal operator which is capable of taking care of the # axes-matching from .operators.diagonal_operator import DiagonalOperator diag = DiagonalOperator(y.conjugate(), self.domain, spaces=spaces, copy=False) dotted = diag(x) return fct*dotted.sum(spaces=spaces) spaces = utilities.cast_iseq_to_tuple(spaces) active_axes = [] for i in spaces: active_axes += self.domain.axes[i] res = 0. for sl in utilities.get_slice_list(self.shape, active_axes): res += dobj.vdot(y.val, x.val[sl]) return res*fct def norm(self): """ Computes the L2-norm of the field values. ... ... @@ -515,7 +521,7 @@ class Field(object): The L2-norm of the field values. """ return dobj.sqrt(dobj.abs(self.vdot(x=self))) return np.sqrt(np.abs(self.vdot(x=self))) def conjugate(self): """ Returns the complex conjugate of the field. ... ... @@ -566,6 +572,10 @@ class Field(object): def sum(self, spaces=None): return self._contraction_helper('sum', spaces) def integrate(self, spaces=None): tmp = self.weight(1, spaces=spaces) return tmp.sum(spaces) def prod(self, spaces=None): return self._contraction_helper('prod', spaces) ... ...