Line data Source code
1 : #pragma once 2 : 3 : #include "elsaDefines.h" 4 : #include "Cloneable.h" 5 : #include "DataContainer.h" 6 : #include "DataDescriptor.h" 7 : #include "StrongTypes.h" 8 : 9 : namespace elsa 10 : { 11 : /** 12 : * @brief Base class representing a proximity operator prox. 13 : * 14 : * @author Andi Braimllari - initial code 15 : * 16 : * @tparam data_t data type for the values of the operator, defaulting to real_t 17 : * 18 : * This class represents a proximity operator prox, expressed through its apply methods, 19 : * which implement the proximity operator of f with penalty r i.e. 20 : * @f$ prox_{f,\rho}(v) = argmin_{x}(f(x) + (\rho/2)ยท\| x - v \|^2_2). @f$ 21 : * 22 : * Concrete implementations of proximity operators will derive from this class and override the 23 : * applyImpl method. 24 : * 25 : * References: 26 : * https://stanford.edu/~boyd/papers/pdf/admm_distr_stats.pdf 27 : */ 28 : template <typename data_t = real_t> 29 : class ProximityOperator : public Cloneable<ProximityOperator<data_t>> 30 : { 31 : public: 32 : /// delete no-args constructor to prevent creation of an object without a DataDescriptor 33 : ProximityOperator() = delete; 34 : 35 : /** 36 : * @brief Override to construct an actual proximity operator for one of the derived classes 37 : * from the given DataDescriptor descriptor 38 : * 39 : * @param[in] descriptor DataDescriptor describing the operator values 40 : */ 41 : ProximityOperator(const DataDescriptor& descriptor); 42 : 43 : /// delete copy construction 44 : ProximityOperator(const ProximityOperator<data_t>&) = delete; 45 : 46 : /// delete implicitly declared copy assignment to prevent copy assignment 47 : auto operator=(const ProximityOperator&) -> ProximityOperator& = delete; 48 : 49 : /// default destructor 50 74 : ~ProximityOperator() override = default; 51 : 52 : /// return the DataDescriptor 53 : auto getRangeDescriptor() const -> const DataDescriptor&; 54 : 55 : /** 56 : * @brief apply the proximity operator to an element in the operator's domain 57 : * 58 : * @param[in] v input DataContainer 59 : * @param[in] t input Threshold 60 : * 61 : * @returns prox DataContainer containing the application of the proximity operator to 62 : * data v, i.e. in the range of the operator 63 : * 64 : * Please note: this method uses apply(v, t, prox(v)) to perform the actual operation. 65 : */ 66 : auto apply(const DataContainer<data_t>& v, geometry::Threshold<data_t> t) const 67 : -> DataContainer<data_t>; 68 : 69 : /** 70 : * @brief apply the proximity operator to an element in the operator's domain 71 : * 72 : * @param[in] v input DataContainer 73 : * @param[in] t input Threshold 74 : * @param[out] prox output DataContainer 75 : * 76 : * Please note: this method calls the method applyImpl that has to be overridden in derived 77 : * classes. (Why is this method not virtual itself? Because you cannot have a non-virtual 78 : * function overloading a virtual one [apply with one vs. two arguments]). 79 : */ 80 : void apply(const DataContainer<data_t>& v, geometry::Threshold<data_t> t, 81 : DataContainer<data_t>& prox) const; 82 : 83 : protected: 84 : std::unique_ptr<DataDescriptor> _rangeDescriptor; 85 : 86 : /// the apply method that has to be overridden in derived classes 87 : virtual void applyImpl(const DataContainer<data_t>& v, geometry::Threshold<data_t> t, 88 : DataContainer<data_t>& prox) const = 0; 89 : 90 : /// overridden comparison method based on the DataDescriptor 91 : auto isEqual(const ProximityOperator<data_t>& other) const -> bool override; 92 : }; 93 : } // namespace elsa