Line data Source code
1 : #include "L1Norm.h" 2 : #include "DataContainer.h" 3 : #include "TypeCasts.hpp" 4 : #include "ProximalL1.h" 5 : 6 : #include <limits> 7 : #include <stdexcept> 8 : 9 : namespace elsa 10 : { 11 : template <typename data_t> 12 : L1Norm<data_t>::L1Norm(const DataDescriptor& domainDescriptor) 13 : : Functional<data_t>(domainDescriptor) 14 70 : { 15 70 : } 16 : 17 : template <typename data_t> 18 : data_t L1Norm<data_t>::evaluateImpl(const DataContainer<data_t>& Rx) const 19 44 : { 20 44 : return Rx.l1Norm(); 21 44 : } 22 : 23 : template <typename data_t> 24 : data_t L1Norm<data_t>::convexConjugate(const DataContainer<data_t>& x) const 25 4 : { 26 4 : auto tmp = ::elsa::cwiseAbs(x).maxElement() - 1; 27 : 28 4 : if (tmp < 1e-5) { 29 2 : return 0; 30 2 : } else { 31 2 : return std::numeric_limits<data_t>::infinity(); 32 2 : } 33 4 : } 34 : 35 : template <typename data_t> 36 : bool L1Norm<data_t>::isProxFriendly() const 37 4 : { 38 4 : return true; 39 4 : } 40 : 41 : template <typename data_t> 42 : DataContainer<data_t> L1Norm<data_t>::proximal(const DataContainer<data_t>& v, 43 : SelfType_t<data_t> t) const 44 8 : { 45 8 : DataContainer<data_t> out(v.getDataDescriptor()); 46 8 : proximal(v, t, out); 47 8 : return out; 48 8 : } 49 : 50 : template <typename data_t> 51 : void L1Norm<data_t>::proximal(const DataContainer<data_t>& v, SelfType_t<data_t> t, 52 : DataContainer<data_t>& out) const 53 8 : { 54 8 : ProximalL1<data_t> prox; 55 8 : prox.apply(v, t, out); 56 8 : } 57 : 58 : template <typename data_t> 59 : void L1Norm<data_t>::getGradientImpl(const DataContainer<data_t>&, DataContainer<data_t>&) const 60 4 : { 61 4 : throw LogicError("L1Norm: not differentiable, so no gradient! (busted!)"); 62 4 : } 63 : 64 : template <typename data_t> 65 : LinearOperator<data_t> L1Norm<data_t>::getHessianImpl(const DataContainer<data_t>&) const 66 4 : { 67 4 : throw LogicError("L1Norm: not differentiable, so no Hessian! (busted!)"); 68 4 : } 69 : 70 : template <typename data_t> 71 : L1Norm<data_t>* L1Norm<data_t>::cloneImpl() const 72 42 : { 73 42 : return new L1Norm(this->getDomainDescriptor()); 74 42 : } 75 : 76 : template <typename data_t> 77 : bool L1Norm<data_t>::isEqual(const Functional<data_t>& other) const 78 22 : { 79 22 : if (!Functional<data_t>::isEqual(other)) 80 0 : return false; 81 : 82 22 : return is<L1Norm>(other); 83 22 : } 84 : 85 : // ------------------------------------------ 86 : // explicit template instantiation 87 : template class L1Norm<float>; 88 : template class L1Norm<double>; 89 : // template class L1Norm<complex<float>>; 90 : // template class L1Norm<complex<double>>; 91 : 92 : } // namespace elsa