Line data Source code
1 : #include "Scaling.h" 2 : #include "Timer.h" 3 : #include "TypeCasts.hpp" 4 : 5 : namespace elsa 6 : { 7 : template <typename data_t> 8 : Scaling<data_t>::Scaling(const DataDescriptor& descriptor, data_t scaleFactor) 9 : : LinearOperator<data_t>(descriptor, descriptor), 10 : _isIsotropic{true}, 11 : _scaleFactor{scaleFactor} 12 4965 : { 13 4965 : } 14 : 15 : template <typename data_t> 16 : Scaling<data_t>::Scaling(const DataDescriptor& descriptor, 17 : const DataContainer<data_t>& scaleFactors) 18 : : LinearOperator<data_t>(descriptor, descriptor), 19 : _isIsotropic{false}, 20 : _scaleFactors{std::make_unique<DataContainer<data_t>>(scaleFactors)} 21 11738 : { 22 11738 : } 23 : 24 : template <typename data_t> 25 : bool Scaling<data_t>::isIsotropic() const 26 12 : { 27 12 : return _isIsotropic; 28 12 : } 29 : 30 : template <typename data_t> 31 : data_t Scaling<data_t>::getScaleFactor() const 32 16 : { 33 16 : if (!_isIsotropic) 34 2 : throw LogicError("Scaling: scaling is not isotropic"); 35 : 36 14 : return _scaleFactor; 37 14 : } 38 : 39 : template <typename data_t> 40 : const DataContainer<data_t>& Scaling<data_t>::getScaleFactors() const 41 26 : { 42 26 : if (_isIsotropic) 43 2 : throw LogicError("Scaling: scaling is isotropic"); 44 : 45 24 : return *_scaleFactors; 46 24 : } 47 : 48 : template <typename data_t> 49 : void Scaling<data_t>::applyImpl(const DataContainer<data_t>& x, DataContainer<data_t>& Ax) const 50 27591 : { 51 27591 : Timer timeguard("Scaling", "apply"); 52 : 53 27591 : if (_isIsotropic) 54 5423 : Ax = _scaleFactor * x; 55 22168 : else 56 22168 : Ax = *_scaleFactors * x; 57 27591 : } 58 : 59 : template <typename data_t> 60 : void Scaling<data_t>::applyAdjointImpl(const DataContainer<data_t>& y, 61 : DataContainer<data_t>& Aty) const 62 14096 : { 63 14096 : Timer timeguard("Scaling", "applyAdjoint"); 64 : 65 14096 : if (_isIsotropic) 66 3035 : Aty = _scaleFactor * y; 67 11061 : else 68 11061 : Aty = *_scaleFactors * y; 69 14096 : } 70 : 71 : template <typename data_t> 72 : Scaling<data_t>* Scaling<data_t>::cloneImpl() const 73 16068 : { 74 16068 : if (_isIsotropic) 75 4585 : return new Scaling(this->getDomainDescriptor(), _scaleFactor); 76 11483 : else 77 11483 : return new Scaling(this->getDomainDescriptor(), *_scaleFactors); 78 16068 : } 79 : 80 : template <typename data_t> 81 : bool Scaling<data_t>::isEqual(const LinearOperator<data_t>& other) const 82 196 : { 83 196 : if (!LinearOperator<data_t>::isEqual(other)) 84 0 : return false; 85 : 86 196 : auto otherScaling = downcast_safe<Scaling>(&other); 87 196 : if (!otherScaling) 88 0 : return false; 89 : 90 196 : if (_isIsotropic != otherScaling->_isIsotropic) 91 0 : return false; 92 : 93 196 : if (_isIsotropic && _scaleFactor != otherScaling->_scaleFactor) 94 4 : return false; 95 : 96 192 : if (!_isIsotropic && *_scaleFactors != *otherScaling->_scaleFactors) 97 0 : return false; 98 : 99 192 : return true; 100 192 : } 101 : 102 : // ------------------------------------------ 103 : // explicit template instantiation 104 : template class Scaling<float>; 105 : template class Scaling<complex<float>>; 106 : template class Scaling<double>; 107 : template class Scaling<complex<double>>; 108 : 109 : } // namespace elsa