Line data Source code
1 : #pragma once 2 : 3 : #include "LinearOperator.h" 4 : 5 : namespace elsa 6 : { 7 : /** 8 : * @brief Operator representing a scaling operation. 9 : * 10 : * @author Matthias Wieczorek - initial code 11 : * @author Maximilian Hornung - minor fixes 12 : * @author Tobias Lasser - modularization, rewrite 13 : * 14 : * @tparam data_t data type for the domain and range of the operator, defaulting to real_t 15 : * 16 : * This class represents a linear operator A that scales the input, either by a scalar 17 : * or by a diagonal scaling matrix. 18 : */ 19 : template <typename data_t = real_t> 20 : class Scaling : public LinearOperator<data_t> 21 : { 22 : public: 23 : /** 24 : * @brief Constructor for a scalar, isotropic scaling operator. 25 : * 26 : * @param[in] descriptor DataDescriptor describing the domain and the range of the operator 27 : * @param[in] scaleFactor the scalar factor to scale with 28 : */ 29 : Scaling(const DataDescriptor& descriptor, data_t scaleFactor); 30 : 31 : /** 32 : * @brief Constructor for a diagonal, anisotropic scaling operator. 33 : * 34 : * @param[in] scaleFactors a DataContainer containing the scaling factor to be put on the 35 : * diagonal 36 : */ 37 : Scaling(const DataContainer<data_t>& scaleFactors); 38 : 39 : /// make copy constructor deletion explicit 40 : Scaling(const Scaling<data_t>&) = delete; 41 : 42 : /// default destructor 43 2357 : ~Scaling() override = default; 44 : 45 : /// is the scaling isotropic 46 : bool isIsotropic() const; 47 : 48 : /// returns the scale factor (throws if scaling is not isotropic) 49 : data_t getScaleFactor() const; 50 : 51 : /// returns the scale factors (throws if scaling is isotropic) 52 : const DataContainer<data_t>& getScaleFactors() const; 53 : 54 : protected: 55 : /// apply the scaling operation 56 : void applyImpl(const DataContainer<data_t>& x, DataContainer<data_t>& Ax) const override; 57 : 58 : /// apply the adjoint of the scaling operation 59 : void applyAdjointImpl(const DataContainer<data_t>& y, 60 : DataContainer<data_t>& Aty) const override; 61 : 62 : /// implement the polymorphic clone operation 63 : Scaling<data_t>* cloneImpl() const override; 64 : 65 : /// implement the polymorphic comparison operation 66 : bool isEqual(const LinearOperator<data_t>& other) const override; 67 : 68 : private: 69 : /// flag if the scaling is isotropic 70 : bool _isIsotropic; 71 : 72 : /// isotropic scaling factor 73 : data_t _scaleFactor; 74 : 75 : /// anisotropic scaling factors 76 : std::unique_ptr<DataContainer<data_t>> _scaleFactors{}; 77 : }; 78 : 79 : template <class data_t> 80 : LinearOperator<data_t> operator*(const LinearOperator<data_t>& lhs, 81 : const DataContainer<data_t>& rhs) 82 20 : { 83 20 : return leaf(lhs * Scaling<data_t>(rhs)); 84 20 : } 85 : 86 : template <class data_t> 87 : LinearOperator<data_t> operator*(const DataContainer<data_t>& lhs, 88 : const LinearOperator<data_t>& rhs) 89 : { 90 : return leaf(Scaling<data_t>(lhs) * rhs); 91 : } 92 : } // namespace elsa